+
    jHàjõ ã                   óÌ  a€ ER” Et}0 t R t^ RIHt ]! 4        ^ 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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 ^ RIHt ^ RIHtH t H!t!H"t"H#t#H$t$H%t% ^ RI&t'^ RI(H)t) ^ R	I*H+t+H,t, ^ R
I-H.t. ^ RI/H0t0H1t1 ^ RI2H3t3 ^ RI4H5t5H6t6H7t7H8t8H9t9H:t:H;t;H<t<H=t= ^ RI4H>t>H?t? ^ RI@HAtAHBtBHCtCHDtD ^ RIEHFtFHGtGHHtHHItIHJtJHKtKHLtLHMtMHNtNHOtO ]P                   ! ]Q4      tRR R ltSR R ltTR R ltU ! R R]V4      tW]	P°                  ! 4       R8H  tY]
P´                  ! R4      t[ER•t\] ^ k ]]! 0 RkRkRkRkRkR kR!kR"kR#kR$k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RNkROkRPkRQkRRkRSkRTkRUkRVkRWkRXkRYkRZkR[kR\kR]kR^kR_kR`kRakRbkRckRdkRekRfk4      t^] ^k RgR/Rh Ri llt_Rj Rk lt`]PÂ                  ! 4       tb/ tc] ^k / td] ^k / te] ^k ]]! 0 RlkRmkRnkRokRpkRqkRrkRskRtkRukRvkRwkRxkRykRzkR{kR|kR}kR~kRkR€kR�kR‚kRƒkR„kR…kR†kR‡kRˆkR‰kRŠkR‹kRŒkR�kRŽkR�kR�kR‘kR’kR“kR”kR•kR–kR—kR˜kR™kRškR›kRœkR�kRžkRŸkR kR¡kR¢kR£kR¤kR¥kR¦kR§kR¨kR©kRªkR«kR¬kR­kR®kR¯kR°kR±kR²kR³kR´kRµkR¶kR·kR¸kR¹kRºkR»kR¼kR½kR¾kR¿kRÀkRÁkRÂkRÃkRÄkRÅkRÆkRÇkRÈkRÉkRÊkRËkR[kR\kRÌkRÍk4      tfRÎRÏ0tg]! RÐ4      thRÑ RÒ ltiRÓtjRÔ RÕ ltk]]! 0 ER–m4      tlRØ RÙ ltmER—RÚ RÛ lltnRÜ RÝ ltoRÞ Rß ltpR×RàRÖRá/tqRâ Rã ltrRä Rå ltsRættRç Rè ltuER˜Ré Rê lltvER™Rë Rì lltwRí Rî ltxRï Rð ltyRñRò/Ró Rô lltzRõ Rö lt{R÷ Rø lt|Rù t}Rú t~ER—Rû Rü lltRý Rþ lt€]�! 4       t‚] ^k ERštƒRÿ t„^ ER I…H†t†H‡t‡ ^ ERIˆH‰t‰HŠtŠH‹t‹HŒtŒH�t�HŽtŽH�t�H�t�H‘t‘H’t’H“t“H”t”H•t•H–t–H—t—H˜t˜H™t™HštšH›t›HœtœH�t�HžtžHŸtŸH t H¡t¡H¢t¢H£t£H¤t¤ ^ ERI¥H¦t§H¨t©HªtªH«t¬ ^ ERI­H®t®H¯t¯ ^. ER›O^ERER	.^. ERœO^
ER.^ER./t°] ^k / t±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 lt¶ERERERERERRò/ER ER llt·]¸! 4       t¹ER ER ltºER  ER! lt»ER" ER# lt¼]]! 0 ER$kRlkRnkERkER%kER&kERkER'kER(kER)kER*kER+kER,kER-kERkER.kER/kERkERkER0kERkER1kER2kER3kER4kR¹kER5kER
kERkER6kER7k4      t½ER8 ER9 lt¾ER: ER; lt¿ER< ER= ltÀER> ER? ltÁ0 ERžmtÂ]]! ]†EP†                  ! 4       4      ]Â,          tÄ0 ERŸmtÅ0 ER mtÆ] ! ERB ERC4      4       tÇERD ERE ltÈER¡ERF ERG lltÉER¢tÊER£tËER¤tÌERH ERI ltÍERJ ERK ltÎERL ERM ltÏERNtÐERO ERP ltÑERQ ERR ltÒERS ERT ltÓERU ERV ltÔERW ERX ltÕER—ERY ERZ lltÖER—ER[ ER\ llt×ER] ER^ ltØER_ ER` ltÙERa ERb ltÚERc ERd ltÛER¥ERe ERf lltÜERg ERh ltÝERi ERj ltÞERk ERl ltßERm ERn ltàERo ERp ltáERq ERr ltâERs ERt ltãERu ERv ltä]
P´                  ! ERw4      tåERx ERy ltæERz ER{ ltçER| ER} ltèER~ ER ltéER€ têER—ER� ltëER‚ tìER—ERƒ ltíER„ ER… ltî]†R3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� ltó]EPè                  tõ]]! 0 ER¦m4      tö]õ3ER’ ER“ llt÷ER”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ž ltüER—ERŸ ER  lltýER¡ ER¢ ltþER—ER£ ER¤ lltÿER§ER¥ ER¦ llEt ER§R/ER¨ ER© llEtER§R/ERª ER« llEtER§R/ER¬ ER­ llEtER® ER¯ lEtER° ER± lEtER² ER³ lEtER´Rò/ERµ ER¶ llEtER·R¸/ER¨ U u/ uF  p V ER¸V EP                  4        2bK  	  up CEt	ER¹ ERº lEt
ER» ER¼ lEtER½ ER¾ lEtER¿ ERÀ lEtERÁ ERÂ lEtERÃRERÄRERÅR/ERÆ ERÇ llEtERÈ ERÉ lEtERÊ ERË lEtERÌ ERÍ lEtERÎ ERÏ lEtERÐ ERÑ lEtERÒEtERÓEtERÔ ERÕ lEtERÖ ER× lEtERØERERÙRERÚRò/ERÛ ERÜ llEtERÝ ERÞ lEtERß ERà lEtERá ERâ lEtERã ERä lEtERå ERæ lEtERç ERè lEt/ Et ] ^k ]EPB                  ! 4       Et"ERé ERê lEt#]ERë ERì l4       Et$ERí ERî lEt%ERï ERð lEt&ERñ ERò lEt'RgR/ERó ERô llEt(ERõ ERö lEt)ER÷ ERø lEt*ERù ERú lEt+ERû ERü lEt,ERý ERþ lEt-ERÿ ER  lEt.ER ER lEt/ER ER lEt0ER—ERER/ER ER lllEt1ER—ER ER	 llEt2ER—ER
 lEt3ER—ER ER llEt4ER ER lEt5ER ER lEt6ER ER lEt7ER ER lEt8ER ER lEt9ER ER lEt:]]! 0 ER©m4      Et;ERªEt<ER«Et=]
P´                  ! ER4      Et>ER ER lEt?ER¬ER ER llEt@ER EtAER ER  lEtB]]! 0 ER­m4      EtC]]! 0 ER®m4      EtD]]! ER@04      EtE]]! ERA04      EtFE]CE]E,          E]D,          EtGER" ER# lEtHER¯ER$ ER% llEtIER& ER' lEtJER( ER) lEtKER* ER+ lEtLER, ER- lEtMER. ER/ lEtNER0ERER1ERER2ERER3RòER4RòER5RòER‘RER�RER6R/	EtOER7 ER8 lEtPER@ER9ER!ER:ER;ER:ER<ER:ER=ER9ER>ER9ER?ER9/EtQ]]! ER@ERA04      EtRERB ERC lEtSERD ERE lEtTERF ERG lEtUERH ERI lEtVERJ ERK lEtWERL ERM lEtXERN ERO lEtYERP ERQ lEtZERR ERS lEt[ER�ERT ERU llEt\ERVRòER´Rò/ERW ERX llEt]ERY ERZ lEt^ER—ER[ ER\ llEt_ER] ER^ lEt`ER_. ER°OR3EtaER`. ER±O. ER²O3EtbERa. ER³OR3EtcERb EtdERc EteERd EtfERe ERf lEtgERg ERh lEthERi EtiERj EtjERk ERl lEtkRERm ERnERo ERpERq ERrE]dERsE]eERtE]fERuERv ERwERx ERyE]iERzE]j/
EtlER{EtmER| EtnER} ER~ lEtoE]o! 4        ]!ER´,          EtpER ER€ lEtqERµER� ER‚ llEtrER—ERƒ ER„ llEtsERµER…RòER†R/ER‡ ERˆ lllEttER¶EtuER‰ER/ERŠ ER‹ llEtvERŒ ER� lEtwER·ER…Rò/ERŽ ER� lllEtxER—ER� ER‘ llEtyER’ ER“ lEtz]]! ]‡4      Et{] ^k E]z! 4       Et|] ^	k R# u up i (¸  zˆConfiguration management for Hermes Agent: config.yaml / .env loading, saving,
validation, migration, and the ``hermes config`` command.)Údrop_stale_root_modulesN)ÚcontextmanagerÚsuppress)Ú	dataclass)ÚDecimalÚInvalidOperation©ÚPath)ÚDictÚAnyÚLiteralÚOptionalÚListÚTupleÚSet)Ú
line_input)ÚColorsÚcolor)Úmanaged_scope)ÚDEFAULT_SOUL_MDÚis_legacy_template_soul)Úmasked_secret_prompt)	Ú_IGNORED_MANAGED_VALUESÚ_LEGACY_MANAGED_SYSTEMÚ_MANAGED_FALSE_VALUESÚ_MANAGED_TRUE_VALUESÚ_chown_to_hermes_uidÚ_container_or_chmod_skippedÚ_resolve_hermes_uid_gidÚapply_secure_dir_policyÚget_managed_system)Úget_hermes_homeÚget_process_hermes_home)Úatomic_replaceÚfast_safe_loadÚfile_signatureÚmkstemp_beside)
Ú_CONFIG_PARSE_FAILURESÚ
_FIX_PERMSÚ	_FIX_YAMLÚFailedConfigReadÚ_backups_dir_displayÚ_refuse_failed_readÚ_refuse_overwriteÚ_warn_config_parse_failureÚ_yaml_error_detailsÚ_yaml_error_locationc                ó$   € V ^8„  d   QhR\         /# ©é   Úreturn©Úbool)Úformats   "Ú6/home/ubuntu/.hermes/hermes-agent/hermes_cli/config.pyÚ__annotate__r9   :   s   € ÷ ñ œDñ ó    c                  ó   € R # ©F© r=   r:   r8   Úis_uv_tool_installr>   :   ó   € ár:   c                ó0   € V ^8„  d   QhR\         R\        /# ©r3   Úmethodr4   ©Ústrr6   )r7   s   "r8   r9   r9   ?   s   € ÷ ñ ¬#ð ´$ñ r:   c                 ó   € R # r<   r=   ©rB   s   &r8   Úis_unsupported_install_methodrG   ?   r?   r:   c                ó0   € V ^8„  d   QhR\         R\         /# rA   ©rD   )r7   s   "r8   r9   r9   D   s   € ÷ ñ ¬sð ´sñ r:   c                 ó   € R # ©Ú r=   rF   s   &r8   Ú"format_unsupported_install_warningrM   D   s   € ár:   c                   ó   € ] tR t^ItRtRtR# )ÚInvalidUserConfigErrorzDRaised when a run that cannot repair config finds invalid user YAML.r=   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r=   r:   r8   rO   rO   I   s   † ÝNr:   rO   ÚWindowsz^[A-Za-z_][A-Za-z0-9_]*$Ú
LD_PRELOADÚLD_LIBRARY_PATHÚLD_AUDITÚLD_DEBUGÚDYLD_INSERT_LIBRARIESÚDYLD_LIBRARY_PATHÚDYLD_FRAMEWORK_PATHÚDYLD_FALLBACK_LIBRARY_PATHÚDYLD_FALLBACK_FRAMEWORK_PATHÚ
PYTHONPATHÚ
PYTHONHOMEÚPYTHONSTARTUPÚPYTHONUSERBASEÚPYTHONEXECUTABLEÚPYTHONNOUSERSITEÚPYTHONBREAKPOINTÚPYTHONCASEOKÚNODE_OPTIONSÚ	NODE_PATHÚPERL5OPTÚPERL5LIBÚPERLLIBÚRUBYOPTÚRUBYLIBÚ	CLASSPATHÚJAVA_TOOL_OPTIONSÚ_JAVA_OPTIONSÚJDK_JAVA_OPTIONSÚGOFLAGSÚ	RUSTFLAGSÚPATHÚSHELLÚBROWSERÚEDITORÚVISUALÚPAGERÚMANPAGERÚGIT_SSH_COMMANDÚGIT_EXEC_PATHÚ	GIT_SHELLÚGIT_SSHÚGIT_ASKPASSÚSSH_ASKPASSÚSUDO_ASKPASSÚ
GIT_EDITORÚGIT_SEQUENCE_EDITORÚ	GIT_PAGERÚGIT_EXTERNAL_DIFFÚGIT_PROXY_COMMANDÚGIT_TEMPLATE_DIRÚGIT_DIRÚBASH_ENVÚENVÚZDOTDIRÚPROMPT_COMMANDÚVIMINITÚEXINITÚHERMES_HOMEÚHERMES_PROFILEÚHERMES_CONFIGÚ
HERMES_ENVÚHERMES_CONFIG_PATHÚHERMES_ENV_PATHÚHERMES_OPTIONAL_MCPSÚHERMES_COPILOT_ACP_COMMANDÚHERMES_COPILOT_ACP_ARGSÚHERMES_YOLO_MODEÚHERMES_ACCEPT_HOOKSÚHERMES_REDACT_SECRETSÚHERMES_INTERACTIVEÚHERMES_EXEC_ASKÚHERMES_GATEWAY_SESSIONÚHERMES_CRON_SESSIONÚHERMES_SINGLE_QUERY_SESSIONÚHERMES_SESSION_KEYÚHERMES_SESSION_PLATFORMÚ
is_windowsc                óR   € V ^8„  d   QhR\         R\        \        ,          R\         /# )r3   Úkeyr£   r4   ©rD   r   r6   )r7   s   "r8   r9   r9   ˆ   s%   € ÷ +ñ +œcð +´(¼4µ.ð +ÌCñ +r:   c               óN   € Vf   \         MTpV'       d   V P                  4       # T # )z�Name used for env policy comparisons: Windows env names are case-insensitive, POSIX not.
The override keeps both semantics testable on any host.)Ú_IS_WINDOWSÚupper)r¥   r£   Úwindowss   &$ r8   Ú_env_var_policy_namer«   ˆ   s#   € ð (Ò/�k°Z€Gß!ˆ3�9‰9‹;Ð* sÐ*r:   c                ó(   € V ^8„  d   QhR\         RR/# )r3   r¥   r4   NrI   )r7   s   "r8   r9   r9   �   s   € ÷ ñ ¬ð °ñ r:   c                óÜ   € \         P                  V 4      '       g   \        RV : 24      h\        V 4      pV\        9   g   VP                  \        4      '       d   \        RV : R24      hR# )zTValidate an env name before a generic persistence write (exposed for batch callers).ú#Invalid environment variable name: zEnvironment variable a$   is on the writer denylist. Names that influence subprocess execution (LD_PRELOAD, PYTHONPATH, PATH, EDITOR, ...) or Hermes runtime location and security policy (HERMES_HOME, HERMES_YOLO_MODE, ...) cannot be persisted via the env writer. If you really need this, edit ~/.hermes/.env directly.N)Ú_ENV_VAR_NAME_REÚmatchÚ
ValueErrorr«   Ú_ENV_VAR_NAME_DENYLISTÚ
startswithÚ_ENV_VAR_NAME_DENY_PREFIXES)r¥   Úpolicy_names   & r8   Úvalidate_env_var_name_for_writer¶   �   sn   € ä×!Ñ! #×&Ò&ÜÐ>¸s¹gÐFÓGÐGÜ& sÓ+€KØÔ,Ô,°×0FÑ0FÔGb×0cÒ0cÜØ# C¡7ð +ð óð 	ñ 1dr:   ÚOPENAI_API_KEYÚOPENAI_BASE_URLÚANTHROPIC_API_KEYÚANTHROPIC_TOKENÚDISCORD_HOME_CHANNELÚDISCORD_HOME_CHANNEL_NAMEÚTELEGRAM_HOME_CHANNELÚTELEGRAM_HOME_CHANNEL_NAMEÚSLACK_HOME_CHANNELÚSLACK_HOME_CHANNEL_NAMEÚSIGNAL_ACCOUNTÚSIGNAL_HTTP_URLÚSIGNAL_ALLOWED_USERSÚSIGNAL_GROUP_ALLOWED_USERSÚSIGNAL_HOME_CHANNELÚSIGNAL_HOME_CHANNEL_NAMEÚSMS_HOME_CHANNELÚSMS_HOME_CHANNEL_NAMEÚDINGTALK_CLIENT_IDÚDINGTALK_CLIENT_SECRETÚDINGTALK_HOME_CHANNELÚDINGTALK_HOME_CHANNEL_NAMEÚFEISHU_APP_IDÚFEISHU_APP_SECRETÚFEISHU_ENCRYPT_KEYÚFEISHU_VERIFICATION_TOKENÚFEISHU_HOME_CHANNELÚFEISHU_HOME_CHANNEL_NAMEÚYUANBAO_HOME_CHANNELÚYUANBAO_HOME_CHANNEL_NAMEÚWECOM_BOT_IDÚWECOM_SECRETÚWECOM_CALLBACK_CORP_IDÚWECOM_CALLBACK_CORP_SECRETÚWECOM_CALLBACK_AGENT_IDÚWECOM_CALLBACK_TOKENÚWECOM_CALLBACK_ENCODING_AES_KEYÚWECOM_CALLBACK_HOSTÚWECOM_CALLBACK_PORTÚWECOM_HOME_CHANNELÚWECOM_HOME_CHANNEL_NAMEÚWEIXIN_ACCOUNT_IDÚWEIXIN_TOKENÚWEIXIN_BASE_URLÚWEIXIN_CDN_BASE_URLÚWEIXIN_HOME_CHANNELÚWEIXIN_HOME_CHANNEL_NAMEÚWEIXIN_DM_POLICYÚWEIXIN_GROUP_POLICYÚWEIXIN_ALLOWED_USERSÚWEIXIN_GROUP_ALLOWED_USERSÚWEIXIN_ALLOW_ALL_USERSÚBLUEBUBBLES_SERVER_URLÚBLUEBUBBLES_PASSWORDÚBLUEBUBBLES_HOME_CHANNELÚBLUEBUBBLES_HOME_CHANNEL_NAMEÚ	QQ_APP_IDÚQQ_CLIENT_SECRETÚQQBOT_HOME_CHANNELÚQQBOT_HOME_CHANNEL_NAMEÚQQ_HOME_CHANNELÚQQ_HOME_CHANNEL_NAMEÚQQ_ALLOWED_USERSÚQQ_GROUP_ALLOWED_USERSÚQQ_ALLOW_ALL_USERSÚQQ_MARKDOWN_SUPPORTÚQQ_STT_API_KEYÚQQ_STT_BASE_URLÚQQ_STT_MODELÚ
IRC_SERVERÚIRC_PORTÚIRC_NICKNAMEÚIRC_CHANNELÚIRC_USE_TLSÚIRC_SERVER_PASSWORDÚIRC_NICKSERV_PASSWORDÚTERMINAL_ENVÚTERMINAL_SSH_KEYÚTERMINAL_SSH_PORTÚHERMES_TOOL_PROGRESS_MODEÚWHATSAPP_MODEÚWHATSAPP_ENABLEDÚMATTERMOST_HOME_CHANNELÚMATTERMOST_HOME_CHANNEL_NAMEÚMATTERMOST_REPLY_MODEÚMATRIX_PASSWORDÚMATRIX_ENCRYPTIONÚMATRIX_DEVICE_IDÚMATRIX_HOME_ROOMÚMATRIX_REQUIRE_MENTIONÚMATRIX_FREE_RESPONSE_ROOMSÚMATRIX_AUTO_THREADÚMATRIX_DM_AUTO_THREADÚMATRIX_RECOVERY_KEYÚHERMES_ACP_AUTH_METHODÚHERMES_ACP_AUTO_APPROVEÚCOPILOT_CLI_PATHÚCOPILOT_ACP_BASE_URLÚnixosúhome-managerz
/nix/storec                ó$   € V ^8„  d   QhR\         /# r2   r5   )r7   s   "r8   r9   r9   æ   s   € ÷ ,ñ ,”Dñ ,r:   c                 ó   € \        4       RJ# )z;Check if Hermes is running in package-manager-managed mode.N©r    r=   r:   r8   Ú
is_managedr  æ   s   € äÓ tÐ+Ð+r:   z£Update Hermes through the Nix source that installed it (e.g. nix profile upgrade, or update your flake input and rebuild with nixos-rebuild or home-manager switch)c                ó:   € V ^8„  d   QhR\         \        ,          /# r2   )r   rD   )r7   s   "r8   r9   r9   ó   s   € ÷ Uñ U¤H¬S¥Mñ Ur:   c                 ó8   € \        4       \        9   d   \        # R# )z;Return the preferred upgrade command for a managed install.N)r    Ú_NIX_MANAGED_SYSTEMSÚ_NIX_UPDATE_MSGr=   r:   r8   Úget_managed_update_commandr#  ó   s   € ä0Ó2Ô6JÔJŒ?ÐTÐPTÐTr:   ÚaptÚdockerc                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r3   Úpathr4   )r	   r   rD   )r7   s   "r8   r9   r9   þ   s"   € ÷ Dñ D¤ð D¬´#­ñ Dr:   c                 ó¢   €  V P                  R R7      P                  4       P                  4       pT\        9   d   T# R#   \         d     R# i ; i)ú	utf-8-sig©ÚencodingN)Ú	read_textÚstripÚlowerÚOSErrorÚ_SUPPORTED_INSTALL_METHODS)r'  rB   s   & r8   Ú_install_method_stampr1  þ   sR   € ðØ—‘¨�Ó5×;Ñ;Ó=×CÑCÓEˆð Ô9Ô9ˆ6ÐC¸tÐCøô ô Úðús   ‚.? ¿AÁAc                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r3   Úproject_rootr4   )r   r	   rD   )r7   s   "r8   r9   r9     s   € ÷ .ñ .¬´­ð .Ä#ñ .r:   c                ó”  € V e   T M	\        4       p\        VR,          4      pV'       d   V# \        \        4       R,          4      pV'       d   VR8X  d   \        4       '       d   V# \	        4       pV'       d!   VP                  4       P                  RR4      #  VP                  4       pV\        8w  d   \        VP                  9   d   R# TR,          p TP                  4       '       g6   TP                  RR7      P                  4       P                  R	4      '       d   R
#  R#   \         d     Lgi ; i  \         d     R# i ; i)a  Detect how Hermes was installed: apt/docker/nix/nixos/home-manager/git/unknown.
Order: code-scoped ``<install tree>/.install_method`` stamp (authoritative) -> legacy
``$HERMES_HOME/.install_method`` -> managed marker -> /nix/store path -> .git dir -> unknown.
The stamp lives next to the code because HERMES_HOME is shared data: a container and a host
install can bind-mount the same home, so a home-scoped ``docker`` stamp would make the host
``hermes update`` refuse to run. A legacy ``docker`` value is therefore ignored unless we are
really inside a container, and being in a container alone never implies 'docker'.

Source installers clone a git checkout and publish ``install-stamp.json``;
the ``.git`` fallback identifies it as a source install. Older installations
may carry ``.install_method``, which remains authoritative for compatibility.
The published image bakes a ``docker`` marker into ``/opt/hermes``. A manual
clone in a container still resolves via ``.git``, not container presence alone.
See issue #34397.
z.install_methodr%  Ú Ú-Únixz.gitr)  r*  zgitdir:ÚgitÚunknown)Úget_project_rootr1  r!   Ú_running_in_containerr    r.  ÚreplaceÚresolveÚ
_NIX_STOREÚparentsr/  Úis_dirr,  r-  r³   )r3  ÚrootrB   ÚmanagedÚresolvedÚgit_paths   &     r8   Údetect_install_methodrE    s   € ð$ (Ò3‰<Ô9IÓ9K€DÜ" 4Ð*;Õ#;Ó<€FßØˆä"¤?Ó#4Ð7HÕ#HÓI€Fß�v Ô)Ô2G×2IÒ2IØˆä Ó"€GßØ�}‰}‹×&Ñ& s¨CÓ0Ð0ðØ—<‘<“>ˆØ”zÔ!¤j°H×4DÑ4DÔ&DÙð
 �f�}€HðØ�?‰?×Ò × 2Ñ 2¸KÐ 2Ó H× NÑ NÓ P× [Ñ [Ð\e× fÒ fÙð !gñ øô ô Ùðûô ô ØÙðús*   Â0D' ÃD8 Ã-4D8 Ä'D5Ä4D5Ä8EÅEc                ó$   € V ^8„  d   QhR\         /# r2   r5   )r7   s   "r8   r9   r9   7  s   € ÷ ñ œtñ r:   c                 óB   €  ^ RI Hp  V ! 4       #   \         d     R# i ; i)z=Import-safe wrapper around ``hermes_constants.is_container``.©Úis_containerF)Úhermes_constantsrI  Ú	ExceptionrH  s    r8   r;  r;  7  s$   € ðÝ1á‹~ÐøÜô Úðús   ‚ ��c                ó0   € V ^8„  d   QhR\         R\        /# rA   rC   )r7   s   "r8   r9   r9   A  s   € ÷ =ñ =¤#ð =¬$ñ =r:   c                ó.   € V R8H  ;'       g
    V \         9   # )zHTrue for every install method Nix owns ("nix", "nixos", "home-manager").r7  )r!  rF   s   &r8   Úis_nix_install_methodrN  A  s   € à�U‰?×<Ð<˜fÔ(<Ñ<Ð<r:   z,docker pull nousresearch/hermes-agent:latestzpkg upgrade hermes-agentc                ó0   € V ^8„  d   QhR\         R\         /# rA   rI   )r7   s   "r8   r9   r9   L  s   € ÷ Bñ B´#ð B¼#ñ Br:   c                ó\   € \        V 4      '       d   \        # \        P                  V R4      # )zAReturn the update command or guidance for a given install method.zhermes update)rN  r"  Ú_UPDATE_COMMAND_BY_METHODÚgetrF   s   &r8   Ú%recommended_update_command_for_methodrS  L  s&   € ä˜V×$Ò$ÜÐÜ$×(Ñ(¨°ÓAÐAr:   c                ó$   € V ^8„  d   QhR\         /# r2   rI   )r7   s   "r8   r9   r9   S  s   € ÷ 3ñ 3¤Cñ 3r:   c                 ó^   € \        4       ;'       g    \        \        \        4       4      4      # )zÆReturn the best update command for the current installation.
Managed state wins over the code-scoped stamp: a managed install can carry a stale stamp
naming an update path the managed guard refuses.)r#  rS  rE  r:  r=   r:   r8   Úrecommended_update_commandrV  S  s-   € ô &Ó'÷ 3ð 3Ô+PÜÔ.Ó0Ó1ó,3ð 3r:   uÂ  âœ— ``hermes update`` doesn't apply inside the Docker container.

Hermes Agent runs as a published image (nousresearch/hermes-agent), not a
git checkout â€” the container has no working tree to pull into.  Update by
pulling a fresh image and restarting your container instead:

  docker pull nousresearch/hermes-agent:latest
  # then restart whatever started the container, e.g.:
  docker compose up -d --force-recreate hermes-agent
  # or, for ad-hoc runs, exit the current container and `docker run` again

Verify the new version after restart:
  docker run --rm nousresearch/hermes-agent:latest --version

Notes:
  â€¢ If you pinned a specific tag (e.g. ``:v0.14.0``) the ``:latest`` tag
    won't move your container â€” pull the newer tag you actually want, or
    switch to ``:latest`` / ``:main`` for rolling updates.  See available
    tags at https://hub.docker.com/r/nousresearch/hermes-agent/tags
  â€¢ On a ``-desktop`` tag (the one carrying Bot Screen)?  Keep the suffix:
    the unsuffixed image has no Xvnc/Xfce and no sudo to add them, so
    pulling it stops the bots' screens from starting.
  â€¢ Your config and session history live under ``$HERMES_HOME`` (``/opt/data``
    in the container, typically bind-mounted from the host) and persist
    across image upgrades â€” re-pulling doesn't lose any state.
  â€¢ Running a fork?  Build your own image with this repo's ``Dockerfile``
    and replace the ``docker pull`` step with your build/push pipeline.c                ó$   € V ^8„  d   QhR\         /# r2   rI   )r7   s   "r8   r9   r9   |  s   € ÷ "ñ "¤cñ "r:   c                 ó   € \         # )zCReturn the user-facing message for ``hermes update`` inside Docker.)Ú_DOCKER_UPDATE_MESSAGEr=   r:   r8   Úformat_docker_update_messagerZ  |  s   € ä!Ð!r:   c                ó0   € V ^8„  d   QhR\         R\         /# )r3   Úactionr4   rI   )r7   s   "r8   r9   r9   �  s   € ÷ Dñ D¤3ð DÌsñ Dr:   c                ó<   € \        4       ;'       g    RpRV  RV R2# )z/Build a user-facing error for managed installs.za package managerúCannot z): this Hermes installation is managed by z:.
Use your package manager to upgrade or reinstall Hermes.r  )r\  Úmanaged_systems   & r8   Úformat_managed_messager`  �  s5   € ä'Ó)×@Ð@Ð-@€Nà
�&�ÐBÀ>ÐBRð SCð 	CðDr:   c                ó$   € V ^8„  d   QhR\         /# )r3   r\  rI   )r7   s   "r8   r9   r9   ‰  s   € ÷ ;ñ ;œ#ñ ;r:   c                óN   € \        \        V 4      \        P                  R7       R# )z+Print user-friendly error for managed mode.©ÚfileN)Úprintr`  ÚsysÚstderr)r\  s   &r8   Úmanaged_errorrh  ‰  s   € ä	Ô
  Ó
(¬s¯z©z×:r:   c                ó:   € V ^8„  d   QhR\         \        ,          /# r2   )r   Údict)r7   s   "r8   r9   r9   Ž  s   € ÷ Rñ R¤¬$¥ñ Rr:   c                 ó–  € \         P                  P                  R4      R8X  d   R# ^ RIHp  V ! 4       '       d   R#  / p\        \        4       R,          RRR7      ;_uu_ 4       pV Fi  pVP                  4       pR	V9   g   K  VP                  R
4      '       d   K5  VP                  R	4      w  rEpVP                  4       WP                  4       &   Kk  	  RRR4       RTP                  RR4      RTP                  RR4      RTP                  RR4      RTP                  RR4      /#   + '       g   i     LZ; i  \         d     R# i ; i)a‰  Read container mode metadata from HERMES_HOME/.container-mode.
Written by the NixOS activation script when container.enable = true; tells the host CLI to
exec into the container instead of running locally. None when container mode is off, when
already inside the container, or when HERMES_DEV=1 is set. Only FileNotFoundError is
swallowed; other errors (permissions, malformed data) propagate.Ú
HERMES_DEVÚ1NrH  z.container-modeÚrr)  r*  Ú=Ú#Úbackendr%  Úcontainer_namezhermes-agentÚ	exec_userÚhermesÚ
hermes_binz /data/current-package/bin/hermes)ÚosÚenvironrR  rJ  rI  Úopenr!   r-  r³   Ú	partitionÚFileNotFoundError)rI  ÚinfoÚfÚliner¥   Ú_Úvalues          r8   Úget_container_exec_infor€  Ž  s  € ô 
‡z�z‡~�~�lÓ# sÔ*Ùå-Ù‡~‚~Ùð	ØˆÜ”/Ó#Ð&7Õ7¸À{×SÕSÐWXÛ�Ø—z‘z“|�Ø˜$–; t§¡°s×';Ô';Ø$(§N¡N°3Ó$7‘M�C˜EØ(-¯©«�DŸ™›Ó%ñ	 ÷ Tð 	�4—8‘8˜I xÓ0Ø˜$Ÿ(™(Ð#3°^ÓDØ�T—X‘X˜k¨8Ó4Ø�d—h‘h˜|Ð-OÓPð	Rð R÷ T×Sûô ô Úðús;   ½'D9 Á$D&ÂD&Â8D&ÃD9 Ä&D6	Ä1D9 Ä6D9 Ä9EÅEc                ó$   € V ^8„  d   QhR\         /# r2   r   )r7   s   "r8   r9   r9   ¯  s   € ÷ -ñ -œñ -r:   c                 ó$   € \        4       R,          # )zGet the main config file path.úconfig.yaml©r!   r=   r:   r8   Úget_config_pathr…  ¯  s   € äÓ˜}Õ,Ð,r:   Úignore_user_configFc                ó(   € V ^8„  d   QhR\         RR/# )r3   r†  r4   Nr5   )r7   s   "r8   r9   r9   ´  s   € ÷ !;ñ !;¼ð !;È$ñ !;r:   c                ó¢  € V '       g%   \         P                  P                  R4      R8X  d   R# \        4       p \	        VRR7      ;_uu_ 4       p\        V4      pRRR4       Xe   \        V\        4      '       d   R# \        R\        V4      P                   24      p^ RIHp T! TR4      p\        T4      pR	T R
T'       d   RT 2MR R2p	Te   T	RT R2,          p	T	R\!        T4       2,          p	\"        P%                  T	4       \'        T	4      Th  + '       g   i     LÄ; i  \         d     R# \         d   pTp Rp?L©Rp?ii ; i)a¬  Reject an existing invalid config before a non-interactive agent run.
Interactive surfaces keep ``load_config()``'s recovery behavior so the operator can repair
the file; a one-shot run has no such chance, and defaults there could silently pick a hosted
provider and spend against ``.env`` credentials. Missing/empty files stay valid first-run
states; ``--ignore-user-config`` / HERMES_IGNORE_USER_CONFIG=1 remain authoritative.ÚHERMES_IGNORE_USER_CONFIGrm  Nr)  r*  z,top-level YAML value must be a mapping, got ©Úbackup_configÚcorruptz+Hermes stopped because your settings file (z) has a formatting errorz at rL   z‡. Fix it with `hermes config edit` and check with `hermes config check`, or add --ignore-user-config to run once with default settings.z! A copy of the broken file is at Ú.z
 Details: )rv  rw  rR  r…  rx  r$   Ú
isinstancerj  Ú	TypeErrorÚtyperP   rz  rK  Úhermes_cli.config_backupsr‹  r0   r/   ÚloggerÚerrorrO   )
r†  Úconfig_pathr|  ÚdataÚparse_errorÚexcr‹  Úbackup_pathÚwhereÚmessages
   $         r8   Úrequire_parseable_user_configr›  ´  s8  € ÷ œRŸZ™ZŸ^™^Ð,GÓHÈCÔOÙä!Ó#€Kð
fÜ�+¨×4Õ4¸Ü! !Ó$ˆD÷ 5ð Š<œ: d¬D×1Ò1ÙÜÐ"NÌtÐTXËz×ObÑObÐNcÐ dÓeˆå7Ù ¨YÓ7€KÜ  Ó-€Eà
5°k°]ÐBZß"ˆT�%�‰>¨Ð
+ð ,`ð	`ð ð ÒØÐ6°{°mÀ1ÐEÕEˆØ�Ô/°Ó<Ð=Ð>Õ>€GÜ
‡L�L�ÔÜ
  Ó
)¨{Ð:÷- 5×4ûäô ÚÜô Ø�ûðús;   ºD* ÁDÁD* ÄD'	Ä"D* Ä*EÄ8EÅEÅE	Å	Ec                ó$   € V ^8„  d   QhR\         /# r2   r   )r7   s   "r8   r9   r9   Ø  s   € ÷ &ñ &”dñ &r:   c                 ó$   € \        4       R,          # )z&Get the .env file path (for API keys).ú.envr„  r=   r:   r8   Úget_env_pathrŸ  Ø  s   € äÓ˜vÕ%Ð%r:   c                ó$   € V ^8„  d   QhR\         /# r2   r   )r7   s   "r8   r9   r9   Ý  s   € ÷ 2ñ 2œ$ñ 2r:   c                 ód   € \        \        4      P                  P                  P                  4       # )z'Get the project installation directory.)r	   Ú__file__Úparentr=  r=   r:   r8   r:  r:  Ý  s!   € ä”‹>× Ñ ×'Ñ'×/Ñ/Ó1Ð1r:   c                ó   € \        V 4      # )uÛ  chmod a directory owner-only (0700) and apply HERMES_UID/GID ownership. No-op when managed;
in a container only an explicit HERMES_HOME_MODE is applied. HERMES_HOME_MODE (e.g. 0701)
overrides the mode so a web server can traverse HERMES_HOME to a served subdirectory without
directory listings.

Also applies ``HERMES_UID``/``HERMES_GID``-based ownership when those env vars are set (#34107 â€” Docker
deployments need this so profile subdirs created at runtime by kanban workers don't land as root:root
and block subsequent uid-mapped workers).

Delegates to the canonical import-safe primitive ``hermes_constants.apply_secure_dir_policy``
so callers outside this package (``get_scratch_dir``) share one implementation (#117347).
)r   ©r'  s   &r8   Ú_secure_dirr¦  â  s   € ô # 4Ó(Ð(r:   c                ó
  € \        4       '       g   \        4       '       d   R#  \        P                  P	                  \        V 4      4      '       d   \        P                  ! V R4       R# R#   \        \        3 d     R# i ; i)zˆchmod a file 0600. Skipped when managed (activation sets 0640 group-readable) or in a
container (mounts often need broader permissions).Ni€  )	r  r   rv  r'  ÚexistsrD   Úchmodr/  ÚNotImplementedErrorr¥  s   &r8   Ú_secure_filer«  ò  s^   € ô ‡|‚|Ô2×4Ò4ÙðÜ�7‰7�>‰>œ#˜d›)×$Ò$Ü�HŠH�T˜5Ö!ñ %øäÔ(Ð)ô Úðús   ¤AA- Á-BÂBc                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# )r3   r”  Útemplater4   )r	   r   r6   )r7   s   "r8   r9   r9   þ  s%   € ÷ ñ ¤$ð ´(¼4µ.ð ÌDñ r:   c                ó  € T;'       g    \        4       R,          pV P                  P                  RRR7       VP                  4       '       d$   \        P
                  ! W4       \        V 4       R# \        \        4       R# )a  Create a missing config.yaml the way the installers do: copy cli-config.yaml.example (the display keys
there are commented out), else write stripped DEFAULT_CONFIG. Never DEFAULT_CONFIG verbatim -- the gateway
merges no defaults, so every written display key becomes a global that beats each platform's own default
(#121230). Shared by ``hermes config edit`` and ``hermes doctor --fix`` so the seeders cannot drift.
Returns True when the template was copied (the fallback, like save_config, writes get_config_path()).zcli-config.yaml.exampleT)r?  Úexist_okF)	r:  r£  Úmkdirr¨  ÚshutilÚcopy2r«  Úsave_configÚDEFAULT_CONFIG)r”  r­  s   &&r8   Úseed_config_filerµ  þ  sc   € ð ×IÐIÔ+Ó-Ð0IÕI€HØ×Ñ×Ñ T°DÐÔ9Ø‡�×ÒÜ�Š�XÔ+Ü�[Ô!ÙÜ”ÔÙr:   c                ó(   € V ^8„  d   QhR\         RR/# )r3   Úhomer4   Nr   )r7   s   "r8   r9   r9     s   € ÷ ñ ¤$ð ¨4ñ r:   c           	     ó&  € V R,          pVP                  4       '       d'    VP                  RR7      p\	        T4      '       g   R#  VP                  \        RR7       \#        T4       R#   \        \        3 d     R# i ; i  \         Ed    TP                  4       '       g   h \        P                  ! RR\        T 4      R7      w  r4 \        P                  ! TR	RR7      ;_uu_ 4       pTP                  \        4       RRR4       M  + '       g   i     M; i\        P                  ! YA4        LØ  \         dL    \        \        4      ;_uu_ 4        \        P                   ! T4       RRR4       h   + '       g   i     h ; ii ; ii ; i)
zŒSeed DEFAULT_SOUL_MD on first run; upgrade a legacy comment-only scaffold in place.
A SOUL.md the user actually customized is never touched.zSOUL.mdr)  r*  Núutf-8z	.SOUL.md.z.seed)ÚprefixÚsuffixÚdirÚw)r¨  r,  r/  ÚUnicodeDecodeErrorr   Ú
write_textr   Ú
is_symlinkÚtempfileÚmkstemprD   rv  ÚfdopenÚwriter<  r   Úunlinkr«  )r·  Ú	soul_pathÚexistingÚfdÚtmp_nameÚhandles   &     r8   Ú_ensure_default_soul_mdrË    s=  € ð �yÕ €IØ×Ñ×Òð	Ø ×*Ñ*°KÐ*Ó@ˆHô ' x×0Ò0ÙðØ×Ñœ_°wÐÔ?ô& �Öøô1 Ô+Ð,ô 	Úð	ûô õ Ø×#Ñ#×%Ò%Øô  ×'Ò'¨{À7ÔPSÐTXÓPYÔZ‰ˆð	Ü—’˜2˜s¨W×5Õ5¸Ø—‘œ_Ô-÷ 6×5×5Ð5úä�JŠJ�xÖ+øÜô 	Üœ'×"Õ"Ü—	’	˜(Ô#÷ #à÷ #Ö"àúð	úðúse   ¡A+ ÁB Á+B Á?B Â!FÂ%%FÃ!D6Ã,DÄ	D6ÄDÄD6Ä6"FÅE8	Å/	FÅ8FÆ	FÆFc                 óÂ   € \        4       p \        V 4      p^ RIHp V! V 4       V\        9   d   V P                  4       '       d   R# ^ RIHp V! V \        \        4       R# )zÞEnsure the ~/.hermes directory skeleton exists with secure permissions.
Memoized per home path: this runs on EVERY ``load_config()`` and the ~14 mkdir/chmod syscalls
made repeated loads the dominant cost of hot read paths.)Úassert_named_profile_home_liveN)Úinitialize_home)	r!   rD   rJ  rÍ  Ú_HERMES_HOME_ENSUREDr@  Úhermes_cli.config_homerÎ  Ú_HERMES_HOME_SUBDIRS)r·  r¥   rÍ  rÎ  s       r8   Úensure_hermes_homerÒ  8  sJ   € ô Ó€DÜ
ˆd‹)€Cõ @Ù" 4Ô(Ø
Ô"Ô" t§{¡{§}¢}ÙÝ6Ù�DÔ.Ô0DÖEr:   )r´  ÚOPTIONAL_ENV_VARS)Ú_API_MODE_ALIASESÚ_CAMEL_ALIASESÚ_KNOWN_PROVIDER_KEYSÚ_PROVIDER_NORMALIZE_WARNEDÚ_canonical_api_modeÚ_coerce_ssl_verifyÚ)_custom_provider_entry_to_provider_configÚ_entries_for_routeÚ _normalize_custom_provider_entryÚ_normalize_provider_modelsÚ_pick_provider_base_urlÚ_route_model_cfgÚ_warn_once_per_providerÚ4apply_custom_provider_extra_headers_to_client_kwargsÚ*apply_custom_provider_tls_to_client_kwargsÚcoerce_provider_idÚfind_provider_entryÚget_compatible_custom_providersÚget_custom_provider_api_modeÚ"get_custom_provider_context_lengthÚ!get_custom_provider_extra_headersÚ$get_custom_provider_model_capabilityÚ+get_custom_provider_session_affinity_headerÚ get_custom_provider_tls_settingsÚis_provider_enabledÚnormalize_extra_headersÚ"providers_dict_to_custom_providersÚstringify_provider_map)ÚNEUTRAL_PERSONALITY_NAMESÚprompt_textÚrender_personality_promptÚresolve_ephemeral_system_prompt)Úcheck_config_versionÚread_config_version_stampÚFIRECRAWL_API_KEYÚBROWSERBASE_API_KEYÚBROWSERBASE_PROJECT_IDÚFAL_KEYÚVOICE_TOOLS_OPENAI_KEYÚELEVENLABS_API_KEYÚSLACK_BOT_TOKENÚSLACK_APP_TOKENÚTAVILY_API_KEYÚTERMINAL_MODAL_MODEc                óh   € V ^8„  d   QhR\         R\        \        \        \        3,          ,          /# )r3   Úrequired_onlyr4   )r6   Úlistrj  rD   r   )r7   s   "r8   r9   r9   w  s'   € ÷ 	(ñ 	(¬ð 	(¼¼dÄ3ÌÀ8½nÕ9Mñ 	(r:   c           
     óþ   € \         R3.pV '       g   VP                  \        R34       V UUUUu. uF;  w  r#VP                  4        F"  w  rE\	        V4      '       d   K  RV/VCRV/CNK$  	  K=  	  upppp# u uppppi )z.Check which environment variables are missing.TFÚnameÚis_required)ÚREQUIRED_ENV_VARSÚappendrÓ  ÚitemsÚget_env_value)r  ÚgroupsÚtabler  Úvar_namer{  s   &     r8   Úget_missing_env_varsr  w  s~   € ä  $Ð'Ð(€FßØ�‰Ô(¨%Ð0Ô1ñ #)ö(á"(ÑˆEØ#Ÿk™kžm‰NˆHÜ˜X×&ô 	?ˆ�Ð>˜TÐ> =°+Ô>á+ñ 	?Ù"(ô(ð (ùõ (s   °*A7
ÁA7
c                óF   € V ^8„  d   QhR\         R\        \         ,          /# ©r3   r¥   r4   )rD   r  )r7   s   "r8   r9   r9   ƒ  s   € ÷ ñ œð ¤¤c¥ñ r:   c                ó‚  € . p. p^ pV\        V 4      8  d‰   W,          pVR8X  d4   W^,           V^,            R8X  d   VP                  R4       V^,          pKR  VR8X  d$   VP                  RP                  V4      4       . pMVP                  V4       V^,          pK˜  VP                  RP                  V4      4       V# )ah  Split a dotted config-key path, honoring backslash-escaped dots (``a\.b`` -> ``a.b``).
Backslashes before any other character are preserved verbatim.

``hermes config set`` uses ``.`` as the nesting separator, so a key that itself contains a literal dot
(e.g. provider names like ``qwen3.5-397b-wafer``) was silently split into bogus nested segments
(#84064).
Ú\r�  rL   )Úlenr  Újoin)r¥   ÚpartsÚcurrentÚiÚchs   &    r8   Ú_split_key_pathr  ƒ  s¨   € ð €EØ€GØ	€AØ
Œc�#‹hŒ,Ø�VˆØ�Œ:˜# !�e A¨¥EÐ*¨cÔ1Ø�N‰N˜3ÔØ��FˆAÙØ�Œ9Ø�L‰L˜Ÿ™ Ó)Ô*Ø‰Gà�N‰N˜2ÔØ	ˆQ�ŠØ	‡L�L�—‘˜Ó!Ô"Ø€Lr:   c          	      ót   € V ^8„  d   QhR\         R\        R\        \        \        \
        3,          ,          /# )r3   Ú	containerr  r4   )rj  r  r   ÚtuplerD   Úint)r7   s   "r8   r9   r9   ž  s.   € ÷ ñ ¤Tð ´$ð ¼8ÄEÌ#ÌsÈ(ÅOÕ;Tñ r:   c                óœ   a a€ \        S \        4      '       d	   S'       g   R# \        V V3R l\        \	        S4      ^ R4       4       R4      # )u«  Return ``(literal_key, n_consumed)`` for the longest dotted literal key present in
*container*, or None. With no multi-segment literal this is the historic plain-split walk.

Dots in config key names are the norm, not the exception â€” model IDs (``grok-4.6``, ``glm-5.3``), Matrix
room IDs (``!room:chat.example.cc``), and versioned provider names all embed dots. Users typing
``providers.myprov.models.grok-4.6.context_length`` do not know the escape syntax exists, so when
navigating an EXISTING mapping we prefer an existing literal key equal to the dot-join of the next N
path segments (longest match wins) over blindly splitting. See #84064 / #80006 / 91095 / #91607 /
#99124.
Nc              3   ó†   <"  € T F6  pR P                  SRV 4      S9   g   K  R P                  SRV 4      V3x € K8  	  R# 5i)r�  N)r  )Ú.0Únr  r  s   & €€r8   Ú	<genexpr>Ú(_greedy_literal_match.<locals>.<genexpr>¬  sE   øé € ÐhÑ+C aÀsÇxÁxÐPUÐVXÐWXÐPYÓGZÐ^gÑGgÔ	!ˆ#�(‰(�5˜˜!�9Ó
˜qÕ	!Ó+Cùs
   ƒA£Aéÿÿÿÿ)rŽ  rj  ÚnextÚranger  )r  r  s   ffr8   Ú_greedy_literal_matchr&  ž  s<   ù€ ô �i¤×&Ò&¯eÙÜÝh¬5´°U³¸QÀÔ+CÓhØóð r:   c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r3   r  Úpartr4   )rj  rD   r   )r7   s   "r8   r9   r9   °  s*   € ÷ 
]ñ 
]¤ð 
]¬Cð 
]´H¼SµMñ 
]r:   c                ór   a€ \        V \        4      '       g   R# VR,           o\        V3R lV  4       R4      # )u?  Existing literal dotted key that creating an intermediate mapping ``part`` would shadow
(``grok-4`` beside ``grok-4.5``) â€” the write would produce a phantom sibling the runtime never
reads, so callers fail loudly instead.

Called when a write is about to CREATE a new intermediate mapping named ``part``. See #84064.
Nr�  c              3   óŠ   <"  € T F8  p\        V\        4      '       g   K  VP                  S4      '       g   K4  Vx € K:  	  R # 5i©N)rŽ  rD   r³   )r  Úkrº  s   & €r8   r!  Ú#_phantom_sibling.<locals>.<genexpr>º  s)   øé € ÐU™I�q¬°A´s×);”ÀÇÁÈV×@T—’›Iùs   ƒA A¹
A)rŽ  rj  r$  )r  r(  rº  s   &&@r8   Ú_phantom_siblingr.  °  s2   ø€ ô �i¤×&Ò&ÙØ�C�Z€FÜÔU™IÓUÐW[Ó\Ð\r:   c                ó$   € V ^8„  d   QhR\         /# ©r3   Ú
dotted_keyrI   )r7   s   "r8   r9   r9   ½  s   € ÷ :dñ :d¤Cñ :dr:   c                óœ  € \        V4      pT p^ pV\        V4      8  Edƒ   W5R p\        V4      ^8H  p\        V\        4      '       d?   V^ ,          pV'       d   W$\	        V4      &   R#  V\	        V4      ,          pT^,          pKw  \        V\        4      '       dâ   \        WF4      p	V	eb   V	w  r«W[,           \        V4      8X  d   W$V
&   R# \        VP                  V
4      \        \        34      '       g   / WJ&   WJ,          pW[,          pKý  V^ ,          pV'       d   W$V&   R# \        WH4      pVe.   VP                  RR4      p\        RV: RV: R	V: R
V R2	4      hVP                  V/ 4      pV^,          pEKn  \        R\        V4      P                   RV: 24      hR#   \
        \        3 d    \        RT: RT: R24      hi ; i)ax  Set a value at a dotted key path, creating intermediate dicts on demand.
Numeric segments index lists; the index must already exist (lists are never grown).

Guards against #17876: before this fix the code unconditionally replaced any non-dict value (including
lists) with ``{}``, silently destroying list-typed config like ``custom_providers`` whenever a caller
used an indexed path.
Dotted key names (#84064 family): when navigating an existing mapping, an existing literal key equal to
the dot-join of the next N segments is preferred over blind splitting (see ``_greedy_literal_match``),
so ``models.grok-4.6.supports_vision`` lands on the real ``grok-4.6`` entry. And when a write WOULD
create a new intermediate mapping that shadows an existing dotted sibling (``grok-4`` beside
``grok-4.5``), it raises ``ValueError`` instead of silently writing a phantom the runtime never reads.
Nz!Cannot navigate into list at key z
: segment z is not a numeric indexr�  z\.zRefusing to create nested key ú in z-: the mapping already contains a literal key zT that contains a dot. If you meant that key, escape its dots with a backslash (e.g. z).zCannot navigate into z at key )r  r  rŽ  r  r  r�  r±   rj  r&  rR  r.  r<  Ú
setdefaultr�  rP   )Úconfigr1  r  r  r  r  Ú	remainingÚat_leafr(  r°   r¥   ÚconsumedÚshadowedÚescapeds   &&&           r8   Ú_set_nestedr;  ½  sí  € ô ˜JÓ'€EØ€GØ	€AØ
Œc�%‹j�.Ø˜"�Iˆ	Ü�i“. AÑ%ˆÜ�gœt×$Ò$Ø˜Q•<ˆDßØ%*œ˜D›	Ñ"Ùð@Ø!¤# d£)Õ,�ð
 ��FŠAÜ˜¤×&Ò&Ü)¨'Ó=ˆEØÒ Ø %‘�Ø•<¤3 u£:Ô-Ø#(˜C‘LÙä! '§+¡+¨cÓ"2´T¼4°L×AÒAØ#%�G‘LØ!�,�Ø•�ÙØ˜Q•<ˆDßØ %˜‘ÙÜ'¨Ó6ˆHØÒ#Ø"×*Ñ*¨3°Ó6�Ü Ø4°T±H¸DÀÁð O6Ø6>±\ð BNØNUÈYÐVXðZó[ð [ð ×(Ñ(¨¨rÓ2ˆGØ��F‹AäÐ3´D¸³M×4JÑ4JÐ3KÈ8ÐT^ÑSaÐbÓcÐcñU øô œzÐ*ô @ÜØ7¸
±~ð FØ#™hÐ&=ð?ó@ð @ð@ús   Á*F% Æ%&GÚclear_api_keyTÚclear_api_modeÚclear_base_urlc                ó˜   € V ^8„  d   QhR\         \        \        3,          R\        R\        R\        R\         \        \        3,          /# )r3   Ú	model_cfgr<  r=  r>  r4   ©rj  rD   r   r6   )r7   s   "r8   r9   r9   ú  sD   € ÷ ñ Ü”Cœ�H�~ðÜ15ðÜNRðäðä%)¬#¬s¨(¥^ñr:   c               ó>  € \        V \        4      '       g   V # V'       dI   V P                  RR4       V P                  RR4       V P                  RR4       V P                  RR4       V'       d   V P                  RR4       V'       d   V P                  RR4       V # )a  Remove stale inline endpoint credentials from a model config.
``model.api_key`` is valid only for explicit custom endpoints; built-in providers resolve
credentials from env/auth.json/the pool. Leftovers keep secrets in config.yaml and can
contaminate later custom resolution paths.Úapi_keyNÚapiÚkey_envÚapi_key_envÚapi_modeÚbase_url)rŽ  rj  Úpop)r@  r<  r=  r>  s   &$$$r8   Ú clear_model_endpoint_credentialsrJ  ú  s|   € ô �i¤×&Ò&ØÐßØ�‰�i Ô&Ø�‰�e˜TÔ"ð 	�‰�i Ô&Ø�‰�m TÔ*ßØ�‰�j $Ô'ßØ�‰�j $Ô'ØÐr:   c                ó$   € V ^8„  d   QhR\         /# )r3   r  ©r  )r7   s   "r8   r9   r9     s   € ÷ ñ ¤$ñ r:   c                ó†  € . pT p^ p WR p\        V\        4      '       d    \        V^ ,          4      pW6,           ^pM.\        V\        4      '       d   \        W54      pVf   R# Vw  rgMR# WG,          pV\        V4      8X  d   W#V3# VP                  W634       W6,          pKŸ    \        \        \
        3 d     R# i ; i)an  Walk *parts* through nested dicts/lists (escape-aware, greedy-literal like ``_set_nested``).
Returns ``(parents, container, key)`` where ``container[key]`` is the addressed leaf and
``parents`` lists the ``(container, key)`` hops above it, or ``None`` when any hop is missing,
a list index is non-numeric/out of range, or a scalar is hit before the path is consumed.N)
rŽ  r  r  r�  r±   Ú
IndexErrorrj  r&  r  r  )	r5  r  r?  r  r  r6  r¥   r8  r°   s	   &&       r8   Ú_locate_nestedrO    sÃ   € ð
 €GØ€GØ	€AØ
Ø˜"�Iˆ	Ü�gœt×$Ò$ðÜ˜) A�,Ó'�Ø–ð ‰HÜ˜¤×&Ò&Ü)¨'Ó=ˆEØŠ}ÙØ!‰MˆC�áØ	�ˆØ”�E“
Œ?Ø SÐ(Ð(Ø�‰˜�~Ô&Ø•,Šøô œz¬:Ð6ô Úðús   £B& Â&C Â?C c                ó$   € V ^8„  d   QhR\         /# r0  rI   )r7   s   "r8   r9   r9   6  s   € ÷ ñ ¤Cñ r:   c                óZ   € \        V \        V4      4      pVf   \        # Vw  r4pWE,          # )aµ  Return a dotted-path value (``_MISSING`` when absent); same navigation as ``_set_nested``
so ``models.grok-4.6.context_length`` reads the real ``grok-4.6`` entry.

Mirrors ``_set_nested``'s navigation: honors backslash-escaped dots and prefers an existing literal
dotted key over blind splitting, so ``config get providers.p.models.grok-4.6.context_length`` reads the
real ``grok-4.6`` entry instead of reporting the key unset (#84064).
)rO  r  Ú_MISSING)r5  r1  Úlocr~  r  r¥   s   &&    r8   Ú_get_nestedrT  6  s1   € ô ˜¤°Ó!<Ó
=€CØ
‚{ÜˆØÑ€A�#Ø�>Ðr:   c                ó0   € V ^8„  d   QhR\         R\        /# )r3   r1  r4   rC   )r7   s   "r8   r9   r9   E  s   € ÷ ñ ¤cð ¬dñ r:   c                óŽ   € \        V \        V4      4      pVf   R# Vw  r4pWE \        V4       F  w  rgV/ 8w  d    R# Wg TpK  	  R# )aj  Remove a dotted-path value; True if it existed. Empty dict containers left behind are
dropped, while user-authored empty lists and non-empty sibling branches are preserved.

Same escape-aware, greedy-literal navigation as ``_set_nested`` / ``_get_nested`` (#84064): unsetting an
unescaped dotted key removes the real literal entry rather than a phantom sibling.
FT)rO  r  Úreversed)r5  r1  rS  r?  r  r¥   r£  r(  s   &&      r8   Ú_unset_nestedrX  E  s]   € ô ˜¤°Ó!<Ó
=€CØ
‚{ÙØÑ€G�cØˆä  Ö)‰ˆØ�bŒ=Øñ ð ˆLØŠñ	 *ñ
 r:   ÚOPENROUTER_API_KEYÚEXA_API_KEYÚPARALLEL_API_KEYÚFIRECRAWL_API_URLÚFIRECRAWL_GATEWAY_URLÚTOOL_GATEWAY_URLÚCONNECTOR_GATEWAY_URLÚTOOL_GATEWAY_DOMAINÚTOOL_GATEWAY_SCHEMEÚTOOL_GATEWAY_USER_TOKENÚPERPLEXITY_API_KEYÚAPI_SERVER_KEYÚBROWSER_USE_API_KEYÚTELEGRAM_BOT_TOKENÚDISCORD_BOT_TOKENÚTERMINAL_SSH_HOSTÚTERMINAL_SSH_USERÚSUDO_PASSWORDÚGITHUB_TOKENÚHONCHO_API_KEYc                ó0   € V ^8„  d   QhR\         R\        /# r  rC   )r7   s   "r8   r9   r9   g  s   € ÷ 
1ñ 
1œCð 
1¤Dñ 
1r:   c                óª   € RV 9   d   R# V P                  4       pV\        9   ;'       g+    VP                  R4      ;'       g    VP                  R4      # )a	  Return whether `hermes config set` routes this credential-shaped key to .env through the
provider credential lifecycle. Non-secret env settings (``*_HOME_CHANNEL``, ``*_ALLOWED_USERS``)
are ``config_env_routing.is_env_setting_key`` and take the plain ``.env`` path.r�  FÚTERMINAL_SSH)Ú_API_KEYÚ_TOKENÚ_SECRET)r©   Ú_ENV_CONFIG_KEYSÚendswithr³   )r¥   Ú	key_uppers   & r8   Ú_is_env_config_keyrv  g  sX   € ð ˆc„zÙØ—	‘	“€IàÔ%Ñ%÷ 	0ð 	0Ø×ÑÐ?Ó@÷	0ð 	0à×Ñ Ó/ð1r:   c                ó0   € V ^8„  d   QhR\         R\        /# )r3   Úas_jsonr4   )r6   rD   )r7   s   "r8   r9   r9   t  s   € ÷ 
ñ 
´ð 
¼ñ 
r:   c               ó,  € V'       d   \         P                  ! V RR7      # \        V \        4      '       d   V '       d   R# R# V f   R# \        V \        \
        34      '       d'   \        P                  ! V RR7      P                  4       # \        V 4      # )z.Format a config value for command-line output.F)Úensure_asciiÚtrueÚfalseÚnull)Ú	sort_keys)
ÚjsonÚdumpsrŽ  r6   rj  r  ÚyamlÚ	safe_dumpÚrstriprD   )r  rx  s   &$r8   Ú_format_config_get_valuer„  t  sm   € çÜ�zŠz˜%¨eÔ4Ð4Ü�%œ×ÒßˆvÐ+ GÐ+Ø‚}ÙÜ�%œ$¤˜×&Ò&Ü�~Š~˜e¨uÔ5×<Ñ<Ó>Ð>Üˆu‹:Ðr:   c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# r2   ©r  rj  rD   r   )r7   s   "r8   r9   r9   �  s    € ÷ ñ ¤4¬¬S´#¨X­Õ#7ñ r:   c                 ó`   a aa€ ^ RI Ho . oRR V VV3R lllo S ! \        \        4       4       S# )z>Check which config fields are missing or outdated (recursive).)Úskip_deep_mergec                ó<   € V ^8„  d   QhR\         R\         R\        /# )r3   Údefaultsr  rº  ©rj  rD   )r7   s   "r8   r9   Ú/get_missing_config_fields.<locals>.__annotate__‡  s!   € ÷ 
>ñ 
>œð 
>¬ð 
>´cñ 
>r:   c           
      ó�  <€ V P                  4        F°  w  r4VP                  R 4      '       d   K  V'       g   TMV RV 2pW19  d   SP                  RVRVRRV 2/4       KQ  \        V\        4      '       g   Ki  \        VP                  V4      \        4      '       g   K�  S! W#4      '       d   K   S! WAV,          V4       K²  	  R# )r~  r�  r¥   ÚdefaultÚdescriptionzNew config option: N)r  r³   r  rŽ  rj  rR  )	rŠ  r  rº  r¥   Údefault_valueÚfull_keyÚ_checkÚmissingrˆ  s	   &&&   €€€r8   r’  Ú)get_missing_config_fields.<locals>._check‡  s§   ø€ Ø"*§.¡.Ö"2ÑˆCØ�~‰~˜c×"Ò"Ùß"(‘s°°¸¸#¸Ð.?ˆHØÔ!Ø—‘  x°¸MØ -Ð1DÀXÀJÐ/Oð Qö Rä˜]¬D×1Ô1´jÀÇÁÈSÓAQÔSW×6XÔ6XÙ+¨F×8Ô8Ù�}¨c¥l°HÖ=ó #3r:   rK   )Úhermes_cli.moa_configrˆ  r´  Úload_config)r’  r“  rˆ  s   @@@r8   Úget_missing_config_fieldsr—  �  s(   ú€ å5à€G÷
>ô 
>ñ Œ>œ;›=Ô)Ø€Nr:   c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# r2   r†  )r7   s   "r8   r9   r9   —  s#   € ÷ ]ñ ]¤t¬D´´c°­NÕ';ñ ]r:   c                 ó�  aa€  ^ RI Hp Ho  T ! 4       pT'       g   . # \        4       oTT3R lT 4       pT UUu. uF;  w  rETe1   \        T\        4      '       g   K!  TP                  4       '       d   K9  TNK=  	  upp#   \         d    . u # i ; i  \         d#   p\        P                  RT4       . u Rp?# Rp?ii ; iu uppi )zVReturn skill-declared config vars (``skills.config.<key>``) that are missing or empty.)Údiscover_all_skill_config_varsÚSKILL_CONFIG_PREFIXz)discover_all_skill_config_vars failed: %sNc           	   3   óv   <"  € T F.  q\        S.S R VR,           2P                  R 4      O5!  3x € K0  	  R# 5i)r�  r¥   N)Úcfg_getÚsplit)r  Úvarr›  r5  s   & €€r8   r!  Ú0get_missing_skill_config_vars.<locals>.<genexpr>¨  s>   øé € ÐlÑckÐ\_”G˜FÐVÐ(;Ð'<¸A¸cÀ%½j¸\Ð%J×%PÑ%PÐQTÓ%UÓVÕWÓckùs   ƒ69)
Úagent.skill_utilsrš  r›  rK  r’  Údebugr–  rŽ  rD   r-  )rš  Úall_varsÚeÚvaluesrŸ  Úvr›  r5  s         @@r8   Úget_missing_skill_config_varsr§  —  s¨   ù€ ðßYðÙ1Ó3ˆ÷
 Øˆ	ä‹]€FÝlÑckÓl€FÙ$Ô\™f‘F�C¨ª	´jÀÄC×6HŒCÐQR×QXÑQX×QZ�CˆC™fÒ\Ð\øô ô ØŠ	ðûô
 ô ä�‰Ð@À!ÔDØ�	ûðüó ]s?   „A? �B ºCÁCÁ5CÁ?BÂBÂB?ÂB:Â4B?Â:B?Úcustom_providersÚ	platformsc                   ó0   a € ] tR tRt o RtV 3R ltRtV tR# )ÚConfigIssueiÑ  z$A detected config structure problem.c                ó>   <€ V ^8„  d   Qh/ S[ ;R&   S[ ;R&   S[ ;R&   # )r3   Úseverityrš  ÚhintrI   )r7   Ú__classdict__s   "€r8   r9   ÚConfigIssue.__annotate__Ñ  s)   ø‡ ‚ ñ �Mñ ñ �Lñ	 ñ
 �Iò r:   r=   N)rP   rQ   rR   rS   rT   Ú__annotate_func__rU   Ú__classdictcell__)r¯  s   @r8   r«  r«  Ñ  s   ø‡ € á.÷ ƒ r:   r«  c          
      ób   € V ^8„  d   QhR\         \        ,          R\        R\        R\        RR/# )r3   Úissuesr­  rš  r®  r4   N)r  r«  rD   )r7   s   "r8   r9   r9   Ù  s5   € ÷ 8ñ 8”4œÕ$ð 8´ð 8¼cð 8Ìð 8ÐQUñ 8r:   c                 ó<   € V P                  \        WV4      4       R # r+  )r  r«  )r´  r­  rš  r®  s   &&&&r8   Ú_issuer¶  Ù  s   € Ø
‡M�M”+˜h°Ó6Ö7r:   c                óÌ   € V ^8„  d   QhR\         \        ,          R\        \        \        3,          R\        R\
        \
        \        \        3,          R3,          R\        RR/# )	r3   r´  ÚentryÚlabelÚfields.r»  r4   N)r  r«  rj  rD   r   r  )r7   s   "r8   r9   r9   Ý  sc   € ÷ [ñ [Ü”Õð[Ü&*¬3´¨8¥nð[Ü=@ð[ä”%œœS˜•/ 3Ð&Õ'ð[ä14ð[à>Bñ[r:   c           
     óz   € V F4  w  rVVP                  V4      '       d   K  \        V RV RV RV 2V4       K6  	  R# )zdAppend a warning for every falsy ``field`` of *entry* (message: ``<label> is missing '<f>' field``).Úwarningz is missing 'z' fieldN)rR  r¶  )r´  r¸  r¹  rº  r»  Úfieldr®  s   &&&&&  r8   Ú_require_fieldsr¾  Ý  s?   € ó ‰ˆØ�y‰y˜×ÔÜ�6˜9¨¨¨}¸U¸GÀ7È6È(Ð&SÐUYÖZó r:   c                ól   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          RR/# ©r3   r5  r´  r4   N©rj  rD   r   r  r«  )r7   s   "r8   r9   r9   ñ  s3   € ÷ fñ fœD¤¤c �Nð f´D¼Õ4Eð fÈ$ñ fr:   c                 ó*  € V P                  R 4      p\        V\        4      '       d   RV9   g   R# VP                  R4      p\        V\        4      '       d   VP	                  4       P                  4       MRpVR9  d   \        VRRV: 2R4       R# R# )ÚvoiceÚsubmit_modeNr“  z3voice.submit_mode must be 'direct' or 'draft', got zSSet voice.submit_mode to direct (submit immediately) or draft (edit before sending)>   ÚdraftÚdirect)rR  rŽ  rj  rD   r-  r.  r¶  )r5  r´  Ú	voice_cfgrÄ  Ú
normalizeds   &&   r8   Ú_validate_voicerÉ  ñ  s…   € Ø—
‘
˜7Ó#€IÜ�y¤$×'Ò'¨M¸YÔ,FÙØ—-‘- Ó.€KÜ0:¸;Ì×0LÒ0L�×"Ñ"Ó$×*Ñ*Ô,ÐRV€JØÐ,Ô,Üˆv�wÐ"UÐVaÑUdÐ eØdö	fñ -r:   c                ól   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          RR/# rÀ  rÁ  )r7   s   "r8   r9   r9   ü  s3   € ÷ Zñ Zœt¤C¬ H�~ð Z´t¼KÕ7Hð ZÈTñ Zr:   c                óÔ  € RV 9  d   R# V P                  R4      pRpVe+   \        V\        4      '       g   \        VRRV: 2V4       R# \        V\        4      '       d   VP	                  4       '       g   R# VP	                  4       p ^ RIpVP                  R4        TP                  T4       R#   \         d     R# i ; i  \         d    \        TRRT: R2T4        R# i ; i)	už  ``timezone`` must be an IANA name the runtime can load.

``hermes_time._get_zoneinfo()`` swallows an invalid name behind a single WARNING in the
gateway log, then runs the agent clock AND every cron schedule on server-local time.
Surface it here, where doctor and the startup check both look. Silent when the
interpreter has no tz database at all (bare Windows without ``tzdata``) â€” nothing can be
judged there.
ÚtimezoneNzïUse an IANA zone name such as America/New_York or Asia/Tokyo (see `timedatectl list-timezones`). With an invalid value the agent clock and cron schedules silently fall back to server-local time. HERMES_TIMEZONE overrides this key when set.r“  z/timezone must be an IANA zone name string, got ÚUTCz	timezone z is not a valid IANA zone name)rR  rŽ  rD   r¶  r-  ÚzoneinfoÚZoneInforK  )r5  r´  Útzr®  r  rÎ  s   &&    r8   Ú_validate_timezonerÑ  ü  sá   € ð ˜ÔÙØ	�‰�JÓ	€Bð!€Dð 
‚~œj¨¬S×1Ò1Üˆv�wÐ"QÐRTÑQWÐ XÐZ^Ô_ÙÜ�rœ3×Ò B§H¡H§J¢JÙØ�8‰8‹:€DðÛØ×Ñ˜%Ô ðZØ×Ñ˜$Öøô ô Úðûô ô ZÜˆv�w )¨D©8Ð3QÐ RÐTX×YðZús$   Â
B3 Â C Â3CÃCÃC'Ã&C'c                óŽ   € V ^8„  d   QhR\         R\        R\         \        ,          R\        \        \        \        3,          RR/# )r3   Úentriesr¹  r´  Únon_dictr4   N)r  rD   r«  r  )r7   s   "r8   r9   r9     sO   € ÷ 
Dñ 
DÜð
DÜð
DÜ'+¬KÕ'8ð
DÜOTÔUXÔZ]Ô_bÐUbÕOcð
Dà	ñ
Dr:   c               óð   € Vw  rVp\        V 4       Fa  w  r‰\        V	\        4      '       g4   \        W%VP	                  V\        V	4      P                  R7      V4       KN  \        W)V RV R2V4       Kc  	  R# )zœValidate each list entry: ``non_dict`` = (severity, message-with-{i}-and-{type}, hint) for
non-dict items; dict items get ``_require_fields`` with *fields*.)r  r�  Ú[Ú]N)Ú	enumeraterŽ  rj  r¶  r7   r�  rP   r¾  )
rÓ  r¹  r´  rº  rÔ  r­  rš  r®  r  r¸  s
   &&&&$     r8   Ú_validate_entry_listrÙ    sh   € ð
 'Ñ€H�tÜ˜gÖ&‰ˆÜ˜%¤×&Ò&Ü�6 W§^¡^°a¼dÀ5»k×>RÑ>R ^Ó%SÐUYÖZä˜F¨e¨W°A°a°S¸¨?¸FÖCó	 'r:   zeChange to:
  custom_providers:
    - name: my-provider
      base_url: https://...
      api_key: ...c                óJ   € V ^8„  d   QhR\         R\        \        ,          RR/# )r3   Úcpr´  r4   N©r   r  r«  )r7   s   "r8   r9   r9   -  s+   € ÷ Yñ Y¤3ð Y´´[Õ0Að YÀdñ Yr:   c                ó–  € \        V \        4      '       d^   \        VRR\        4       \	        V P                  4       4      \        ,          pV'       d   \        VRR\        V4       R2R4       R# R# \        V \        4      '       d   \        V RV\        RR7       R# \        VRR	\        V 4      P                   R
2\        4       R# )uc   custom_providers must be a list of dicts â€” a dict or a scalar is silently dropped by the runtime.r“  uO   custom_providers is a dict â€” it must be a YAML list (items prefixed with '-')r¼  zRoot-level keys z( look like custom_providers entry fieldszLThese should be indented under a '- name: ...' list entry, not at root levelr¨  ©rÔ  zcustom_providers is a un    â€” it must be a YAML list (items prefixed with '-'); legacy custom_providers entries are ignored until it isN)r¼  z0custom_providers[{i}] is not a dict (got {type})z1Each entry should have at minimum: name, base_url)rŽ  rj  r¶  Ú_CP_LIST_HINTÚsetÚkeysÚ_CUSTOM_PROVIDER_LIKE_FIELDSÚsortedr  rÙ  Ú_CP_REQUIRED_FIELDSr�  rP   )rÛ  r´  Ú
suspiciouss   && r8   Ú_validate_custom_providersræ  -  s»   € ä�"”d×ÒÜˆv�wØ`Ôboô	qä˜Ÿ™›“^Ô&BÕBˆ
ßÜ�6˜9Ø%¤f¨ZÓ&8Ð%9Ð9aÐbØaöcñ ô 
�Bœ×	Ò	Ü˜RÐ!3°VÔ=Pð \A÷ 	Bô 	ˆv�wØ'¬¨R«×(9Ñ(9Ð':ð ;Ið IÜJWö	Yr:   c                óJ   € V ^8„  d   QhR\         R\        \        ,          RR/# )r3   Úfbr´  r4   NrÜ  )r7   s   "r8   r9   r9   C  s+   € ÷ Añ A¤ð A¬d´;Õ.?ð AÀDñ Ar:   c                ó  € \        V \        4      '       d   \        V RV\        R	R7       R# \        V \        4      '       g'   \        VRR\        V 4      P                   2R4       R# V '       d   \        WR\        RR7       R# R# )
z5fallback_model: single dict OR list of dicts (chain).Úfallback_modelr“  rÞ  zAfallback_model should be a dict with 'provider' and 'model', got zZChange to:
  fallback_model:
    provider: openrouter
    model: anthropic/claude-sonnet-4u    â€” fallback will be disabled)r»  N)r“  z0fallback_model[{i}] should be a dict, got {type}z!Each entry needs provider + model)
rŽ  r  rÙ  Ú_FB_REQUIRED_FIELDSrj  r¶  r�  rP   r¾  Ú_FB_SINGLE_REQUIRED_FIELDS)rè  r´  s   &&r8   Ú_validate_fallback_modelrí  C  s|   € ä�"”d×ÒÜ˜RÐ!1°6Ô;Nð Zn÷ 	oä˜œD×!Ò!Üˆv�wØRÔSWÐXZÓS[×SdÑSdÐReÐfØnö	p÷ 
Ü˜Ð$4Ô6PØ?÷	Añ 
r:   c                ól   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          RR/# rÀ  rÁ  )r7   s   "r8   r9   r9   Q  s4   € ÷ \ñ \¤4¬¬S¨¥>ð \¼4ÄÕ;Lð \ÐQUñ \r:   c                óÈ  € V P                  R4      p\        V\        4      '       g   R#  ^ RIHp \        4       pR F�  p\        TP                  T4      ;'       g    R4      P                  4       P                  4       pT'       d   Yd9   d   KS  TP                  T4       T! RT4      pT'       g   Kw  \        TRRT RT RT R	2R
4       K‘  	  R#   \
         d     R# i ; i)z£A stale web backend selection otherwise fails only at the first web_search/web_extract
call with a generic "no registered provider" error; warn at startup instead.ÚwebN)Úremoved_backend_noterL   r¼  zweb.z is set to 'z', but u9    â€” web_search/web_extract will fail until it is changedzERun 'hermes tools' and pick a different Web Search & Extract provider)rq  Úsearch_backendÚextract_backend)rR  rŽ  rj  Útools.tool_backend_helpersrñ  rK  rà  rD   r-  r.  Úaddr¶  )r5  r´  Úweb_cfgrñ  ÚseenÚ_keyÚ_valÚnotes   &&      r8   Ú_validate_web_backendsrû  Q  sÔ   € ð �j‰j˜Ó€GÜ�gœt×$Ò$ÙðÝCô “€DÛ@ˆÜ�7—;‘;˜tÓ$×*Ð*¨Ó+×1Ñ1Ó3×9Ñ9Ó;ˆß�t”|ÙØ�‰�ŒÙ# E¨4Ó0ˆß‰4Ü�6˜9Ø˜$˜˜|¨D¨6°¸¸ð ?Jð JàZö\ó Aøô ô Úðús   «C ÃC!Ã C!c                óF   € V ^8„  d   QhR\         \        \        3,          /# r2   r‹  )r7   s   "r8   r9   r9   j  s   € ÷ ñ œ$œs¤C˜x�.ñ r:   c                 óf   a a€ / o R V V3R lloS! \         R4       S P                  \        4       S # )z°Dotted key -> ``"list"``/``"mapping"`` for every slot the schema fixes to a container:
``DEFAULT_CONFIG`` (sections included) plus the known-container table for roots it omits.c                óV   € V ^8„  d   QhR\         \        \        3,          R\        RR/# )r3   Únoderº  r4   N©rj  rD   r   )r7   s   "r8   r9   Ú&_container_slots.<locals>.__annotate__o  s)   € ÷ %ñ %”4œœS˜•>ð %¬3ð %°4ñ %r:   c                 óà   <€ V P                  4        FX  w  r#V'       d   V R V 2MTp\        V\        4      '       d   RSV&   S! W44       K;  \        V\        4      '       g   KS  RSV&   KZ  	  R# )r�  Úmappingr  N)r  rŽ  rj  r  )rÿ  rº  r¥   r  r'  ÚslotsÚwalks   &&   €€r8   r  Ú_container_slots.<locals>.walko  s]   ø€ ØŸ*™*ž,‰JˆCß(.�f�X˜Q˜s˜eÑ$°CˆDÜ˜%¤×&Ò&Ø'��d‘Ù�UÖ!Ü˜E¤4×(Ô(Ø$��d“ó 'r:   rL   )r´  ÚupdateÚ_KNOWN_CONTAINER_TYPES)r  r  s   @@r8   Ú_container_slotsr	  j  s2   ù€ ð €E÷%ñ %ñ 	Œ˜ÔØ	‡L�LÔ'Ô(Ø€Lr:   c                ól   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          RR/# rÀ  rÁ  )r7   s   "r8   r9   r9   }  s/   € ÷ :ñ :¬¬S´#¨X­ð :ÄÄ[Õ@Qð :ÐVZñ :r:   c                óú  € \        4       P                  4        FÂ  w  r#V\        9   d   K  \        V .VP	                  R4      O5!  p\        V\        4      '       d   \        V4      '       g   KW   \        P                  ! V4      p\        T\        \        34      '       g   KŒ  \        TRT RT: RT R2RT R\        P                  ! T4       RT R	24       KÄ  	  R
#   \        P                   d     Kà  i ; i)u  A container slot holding ONE quoted string (``enabled: '["a","b"]'``) is skipped by every
isinstance-gated reader while ``config get`` echoes it back, so plugins silently unmount and
exclusions silently lapse (#83308, #105706). Finding only â€” the file is never rewritten.r�  r¼  z is the quoted string u    â€” Hermes expects a YAML z) here and every reader ignores the stringzRun: hermes config set r5  z  (stores a real z&), or remove the quotes in config.yamlN)r	  r  Ú_SCALAR_AS_ONE_ITEM_LIST_KEYSr�  rž  rŽ  rD   Ú_looks_structured_valuer�  Ú	safe_loadÚ	YAMLErrorr  rj  r¶  ÚshlexÚquote)r5  r´  r¥   Úkindr  Úparseds   &&    r8   Ú_validate_quoted_containersr  }  sï   € ô &Ó'×-Ñ-Ö/‰	ˆàÔ/Ô/ÙÜ˜Ð0 §¡¨3£Ó0ˆÜ˜%¤×%Ò%Ô-DÀU×-KÒ-KÙð	Ü—^’^ EÓ*ˆFô �fœt¤T˜l×+Ô+Ü�6˜9Ø�UÐ0°±	Ð9TÐUYÐTZð [9ð 9à,¨S¨E°´5·;²;¸uÓ3EÐ2FÐFWÐX\ÐW]ð ^9ð 9ö:ó 0øô �~‰~ô 	Úð	ús   Á1C!Ã!C:Ã9C:c                ó~   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        \
        ,          /# ©r3   r5  r4   )r   rj  rD   r   r  r«  )r7   s   "r8   r9   r9   ”  s,   € ÷ (ñ (¤h¬t´C¼°H­~Õ&>ð (Ì$Ì{ÕJ[ñ (r:   c           	     óÖ  € V f    \        4       p . p\	        W4       \        W4       V P                  R4      pV P                  R4      pV\        3V\        33 F  w  rgVf   K  V! Wc4       K  	  \        V\        4      '       d'   RV 9  d    RT;'       g    / 9   d   \        VRRR4       V'       d&   V P                  R4      '       g   \        VR	R
R4       V  FL  pVP                  R4      '       d   K  V\        9  g   K)  V\        9   g   K6  \        VR	RV R2RV R24       KN  	  \        W4       \!        W4       V#   \         d   p^ RIHp T! T4      .u Rp?# Rp?ii ; i)z§Validate config.yaml structure and return detected issues (accepts a pre-loaded dict).
Catches common YAML mistakes that otherwise surface as confusing runtime errors.N)Úconfig_load_issuer¨  rê  r“  zGfallback_model appears inside custom_providers instead of at root levelzDMove fallback_model to the top level of config.yaml (no indentation)Úmodelr¼  u[   custom_providers defined but no 'model' section â€” Hermes won't know which provider to useziAdd a model section:
  model:
    provider: custom
    default: your-model-name
    base_url: https://...r~  zRoot-level key 'uW   ' looks misplaced â€” should it be under 'model:' or inside a 'custom_providers' entry?zMove 'z' under the appropriate section)r–  rK  rÐ  r  rÉ  rÑ  rR  ræ  rí  rŽ  rj  r¶  r³   Ú_KNOWN_ROOT_KEYSrâ  rû  r  )	r5  r—  r  r´  rÛ  rè  r  Ú	validatorr¥   s	   &        r8   Úvalidate_config_structurer  ”  sm  € ð ‚~ð	,Ü “]ˆFð
 !#€FÜ�FÔ#Ü�vÔ&Ø	�‰Ð&Ó	'€BØ	�‰Ð$Ó	%€BØ Ô"<Ð=ÀÔD\Ð?]Ó^ÑˆØÔÙ�eÖ$ñ _ô �"”d×ÒÐ 0¸Ô >ÐCSÐXZ×X`ÐX`Ð^`ÔCaÜˆv�wÐ iØUô	W÷ 
�&—*‘*˜W×%Ò%Üˆv�yØlð+ô	,ó ˆØ�~‰~˜c×"Ô" sÔ2BÖ'BÀsÔNjÖGjÜ�6˜9Ø% c Uð  +Bð  CØ˜C˜5Ð ?Ð@öBñ ô ˜6Ô*Ü Ô/Ø€MøôE ô 	,Ý@Ù% cÓ*Ð+Õ+ûð	,ús   †
E ÅE(ÅE#ÅE(Å#E(c                ó`   € V ^8„  d   QhR\         \        \        \        3,          ,          RR/# ©r3   r5  r4   N©r   rj  rD   r   )r7   s   "r8   r9   r9   ¿  s'   € ÷ 0ñ 0¤(¬4´´S°­>Õ":ð 0Àdñ 0r:   c                óh  €  \        V 4      pV'       g   R# R.pV F9  pVP                  R8X  d   RMRpVP                  RV RVP                   24       K;  	  VP                  R4       \
        P                  P                  R	P                  V4      R
,           4       R#   \         d    . p L£i ; i)zSPrint config structure warnings to stderr at startup; nothing if config is healthy.Nu3   [33mâš  Config issues detected in config.yaml:[0mr“  u   [31mâœ—[0mu   [33mâš [0mú  r5  z2  [2mRun 'hermes doctor' for fix suggestions.[0mÚ
ú

)	r  rK  r­  r  rš  rf  rg  rÄ  r  )r5  r´  ÚlinesÚciÚmarkers   &    r8   Úprint_config_warningsr'  ¿  s¡   € ðÜ*¨6Ó2ˆ÷ ÙàHÐI€EÛˆØ)+¯©¸Ô)?Ñ%ÐEYˆØ�‰�r˜&˜  2§:¡: ,Ð/Ö0ñ ð 
‡L�LÐKÔLÜ‡J�J×Ñ�T—Y‘Y˜uÓ%¨Õ.Ö/øô ô ØŠðús   ‚B! Â!B1Â0B1c                ó   € V ^8„  d   QhRR/# ©r3   r4   Nr=   )r7   s   "r8   r9   r9   Ð  s   € ÷ 4ñ 4 dñ 4r:   c                 ó  €  \        4       p . pR FW  p\        T P                  T4      ;'       g    R4      P	                  4       pT'       g   K?  TP                  RT RT R24       KY  	  T'       d}   ^ RIHp T! 4       pTP                  ^ R4       TP                  R4       TP                  R	T R
24       \        P                  P                  RP                  T4      R,           4       R# R#   \         d     R# i ; i)zÚWarn if MESSAGING_CWD / TERMINAL_CWD is set in .env (canonical: terminal.cwd in config.yaml).
Reads the file rather than ``os.environ`` because runtime bridges and session restoration
legitimately set ``TERMINAL_CWD``.NrL   u     [33mâš [0m ro  u&    found in .env â€” this is deprecated.)Údisplay_hermes_homeu/   [33mâš  Deprecated .env settings detected:[0mzN  [2mMove to config.yaml instead:  terminal:\n    cwd: /your/project/path[0mz'  [2mThen remove the old entries from z	/.env[0mr"  r#  )ÚMESSAGING_CWDÚTERMINAL_CWD)Úload_envrK  rD   rR  r-  r  rJ  r+  Úinsertrf  rg  rÄ  r  )Úenv_mapr$  r  Úvalr+  Ú	hint_paths         r8   Úwarn_deprecated_cwd_env_varsr3  Ð  sæ   € ðÜ“*ˆð €EÛ1ˆÜ�'—+‘+˜dÓ#×)Ð) rÓ*×0Ñ0Ó2ˆß‰3Ø�L‰LÐ0°°°a¸°uÐ<bÐcÖdñ 2÷ Ý8á'Ó)ˆ	Ø�‰�QÐOÔPØ�‰ð=ô	>ð 	�‰ÐAÀ)ÀÈLÐYÔZÜ�
‰
×Ñ˜Ÿ™ 5Ó)¨FÕ2Ö3ñ øô ô Úðús   ‚
C1 Ã1D Ã?D c                óJ   € V ^8„  d   QhR\         \        \        3,          RR/# r  r   )r7   s   "r8   r9   r9   ê  s"   € ÷ 	ñ 	œt¤C¬ H�~ð 	°$ñ 	r:   c                ó€   € ^ RI Hp V! 4       ;_uu_ 4        \        V 4       RRR4       R#   + '       g   i     R# ; i)a£  Persist a migrated config under THE migration write invariant: a migration may only
persist values that DIFFER from the schema default, plus explicit removals/renames of user
data. Every migration step MUST write through here (``save_config`` with default-stripping
ON, no ``merge_existing``) so the invariant cannot regress one migration at a time. A migration
is Hermes' own write, never a user turning a feature off.)Úhermes_applied_writeN)Ú0hermes_cli.observability.shared_metrics_disabledr6  r³  )r5  r6  s   & r8   Ú_persist_migrationr8  ê  s(   € õ Vá	×	Õ	Ü�FÔ÷ 
 ×	×	Ò	ús   –,¬=	c          
      ó˜   € V ^8„  d   QhR\         R\        \         \        3,          R\         R\        \         \        3,          R\        /# )r3   r  r{  ÚpromptÚresultsr4   )rD   rj  r   r6   )r7   s   "r8   r9   r9   ö  sE   € ÷ ñ œsð ¬$¬s´C¨x­.ð Ä#ð ÔPTÔUXÔZ]ÐU]ÕP^ð Ôcgñ r:   c                óò   € VP                  R4      '       d   \        V4      M\        V4      P                  4       pV'       g   R# \	        W4       VR,          P                  V 4       \        RV  24       R# )z`Prompt for one env var (masked when ``info['password']``), save it, record it; False if skipped.ÚpasswordFÚ	env_addedõ     âœ“ Saved T)rR  r   r   r-  Úsave_env_valuer  re  )r  r{  r:  r;  r  s   &&&& r8   Ú_prompt_and_save_envrA  ö  s_   € à,0¯H©H°Z×,@Ò,@Ô  Ô(ÄjÐQWÓFX×F^ÑF^ÓF`€EßÙÜ�4ÔØˆKÕ×Ñ Ô%Ü	ˆL˜˜Ð
Ô Ùr:   c                ó0   € V ^8„  d   QhR\         R\        /# )r3   r:  r4   rC   )r7   s   "r8   r9   r9     s   € ÷ "ñ "œð "¤ñ "r:   c                 óŽ   €  \        V 4      P                  4       P                  4       pVR9   #   \        \        3 d    R p Li ; i)r   >   ÚyÚyes)Úinputr-  r.  ÚEOFErrorÚKeyboardInterrupt)r:  Úanswers   & r8   Ú_ask_yes_norJ    sK   € ðÜ�v“×$Ñ$Ó&×,Ñ,Ó.ˆð �\Ñ!Ð!øô Ô'Ð(ô ØŠðús   ‚'. ®AÁAc                ó^   € V ^8„  d   QhR\         R\         R\        \        \        3,          /# )r3   ÚinteractiveÚquietr4   ©r6   rj  rD   r   )r7   s   "r8   r9   r9   	  s.   € ÷ Jñ J¤ð J´Dð JÄTÌ#ÌsÈ(Å^ñ Jr:   c                óx  € R. R. R. /p\        RR7      w  r4Vf   ^ MTp \        4       pV'       d   V'       g   \        RV R24       ^ R	IHpHpHp	 TRJp
T
;'       d    YW8  ;'       d    YT8  pT'       dZ   T	! 4       pTR,          P                  T4       \        P                  P                  R
T R24       T'       g   \        RT 24       MT! YRY'       * R7       \        Y!4       \        Y!4       YT8  d"   T'       g   T'       g   \        RT RT 24       \        RR7      pT'       d<   T'       g4   \        R4       T F"  p\        RTR,           RTR,           24       K$  	  T '       dœ   T'       d”   \        R4       T F‚  pTP                  R4      '       d   \        RTR,           24       \!        TR,          TRTR,           R2T4      '       g$   TR,          P                  RTR,           R24       \        4        K„  	  T '       d   T'       g   \#        YTT4       TR,          P%                  R \'        4        4       4       YT8  d"   T'       g   \)        4       pYOR&   \+        T4       \-        4       pT'       d   T '       d   T'       g   \/        TT4       T#   \         d     ELoi ; i)zDMigrate config to latest version, prompting for new required fields.r>  Úconfig_addedÚwarningsT©Úraise_on_parse_errorNu'     âœ“ Normalized .env line formatting (z line(s) changed))ÚSUPPORT_FLOOR_VERSIONÚrun_migrationsÚsupport_floor_messageu   âš  hermes config: r"  õ     âš  )ÚunversionedzConfig version: õ    â†’ ©r  u0   
âš ï¸�  Missing required environment variables:u      â€¢ r  ú: r�  z
Let's configure them now:
Úurlú  Get your key at: r!  r:  úSkipped z - some features may not workc              3   ó2   "  € T F  qR ,          x € K  	  R# 5i©r¥   Nr=   )r  r½  s   & r8   r!  Ú!migrate_config.<locals>.<genexpr>H  s   é € Ð"YÑ=X°E¨§<¢<Ó=Xùs   ‚Ú_config_version)rõ  Úsanitize_env_filere  rK  Úhermes_cli.config_migrationsrT  rU  rV  r  rf  rg  rÄ  Ú_disable_suspicious_mcp_serversÚ_warn_invalid_platform_toolsetsr  rR  rA  Ú_offer_new_optional_env_varsÚextendr—  Úread_raw_configr8  r§  Ú_offer_skill_config_vars)rL  rM  r;  ÚstampÚ
latest_verÚcurrent_verÚfixesrT  rU  rV  Úhas_explicit_versionÚfloor_refusedÚmsgÚmissing_envrŸ  r5  Úmissing_skill_configs   &&               r8   Úmigrate_configrt  	  s\  € à˜B °°JÀÐC€Gô 2ÀtÔLÑ€EØ’}‘!¨%€KðÜ!Ó#ˆßŸÜÐ;¸E¸7ÐBSÐTÔU÷Fñ Fð !¨Ð,Ðà×aÐa Ñ!D×aÐaÈÑIað çÙ#Ó%ˆØ�
Õ×"Ñ" 3Ô'ä�
‰
×ÑÐ.¨s¨e°2Ð6Ô7ßÜ�F˜3˜%�.Ô!øá�{¨UÔ@XÕYä# GÔ3Ü# GÔ3àÔ¯·mÜÐ   ¨U°:°,Ð?Ô@ä&°TÔ:€KßŸ5ÜÐAÔBÛˆCÜ�G˜C �K˜=¨¨3¨}Õ+=Ð*>Ð?Ö@ñ ç—{ÜÐ-Ô.ÛˆCØ�w‰w�u�~Š~ÜÐ+¨C°­J¨<Ð8Ô9Ü'¨¨F­°S¸B¸sÀ8½}¸oÈRÐ:PÐRY×ZÒZØ˜
Õ#×*Ñ*¨X°c¸&µk°]ÐB_Ð+`ÔaÜŽGñ ÷ Ÿ5Ü$ [¸gÔFð ˆNÕ×"Ñ"Ñ"YÔ=VÔ=XÓ"YÔYàÔ¯Ü Ó"ˆØ$.Ð Ñ!Ü˜6Ô"ä8Ó:Ðß§·EÜ Ð!5°wÔ?à€Nøô{ ô Úðús    J* ºJ* Ê*J9Ê8J9c                óV   € V ^8„  d   QhR\         \        \        3,          R\        RR/# ©r3   r;  rM  r4   NrA  )r7   s   "r8   r9   r9   V  s)   € ÷ #ñ #¬T´#´s°(­^ð #ÄDð #ÈTñ #r:   c                ó   € \        4       pVP                  R4      p\        V\        4      '       g   R#  ^ RIHp RpTP                  4        F‚  w  rg\        T\        4      '       d	   T! Yg4      MRpT'       g   K/  RTR&   RpT R,          P                  RT R	24       T'       d   K\  T F  p	\        R
T	 24       K  	  \        RT R24       K„  	  T'       d   Y2R&   \        T4       R# R#   \         d     R# i ; i)z¡Post-migration: disable exfiltration-shaped MCP stdio entries (hand-edited or from older
installs). The stanza is preserved for auditability but marked disabled.Úmcp_serversN)Úvalidate_mcp_server_entryFÚenabledTrQ  z Disabled suspicious MCP server 'Ú'rW  u     âš  Disabled MCP server 'z' pending review)ri  rR  rŽ  rj  Úhermes_cli.mcp_securityry  rK  r  r  re  r8  )
r;  rM  r5  Úraw_mcp_serversry  Úmcp_touchedÚserver_namer¸  r´  Úissues
   &&        r8   re  re  V  sþ   € ô Ó€Fð —j‘j Ó/€OÜ�o¤t×,Ò,ÙðÝEð €KØ-×3Ñ3Ö5ÑˆÜBLÈUÔTX×BYÒBYÑ*¨;Ô>Ð_cˆßÙØ ˆˆiÑØˆØ�
Õ×"Ñ"Ð%EÀkÀ]ÐRSÐ#TÔUß‰uÛ�Ü˜˜u˜gÐ&Ö'ñ  äÐ/°¨}Ð<LÐMÖNñ 6÷ Ø /ˆ}ÑÜ˜6Ö"ñ øô ô Úðús   µC. Ã.C=Ã<C=c                óV   € V ^8„  d   QhR\         \        \        3,          R\        RR/# rv  rA  )r7   s   "r8   r9   r9   t  s.   € ÷ Nñ N¬T´#´s°(­^ð NÄDð NÈTñ Nr:   c                ó4  €  ^ RI HpHp \        4       pV! VP	                  R4      V! V4      4       F3  pV R,          P                  V4       V'       d   K%  \        RV 24       K5  	  R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)zµSurface invalid toolset names in platform_toolsets: ``resolve_toolset()`` returns [] for an
unknown name, silently disabling the affected tools. Best-effort; never blocks migration.)Úsaved_toolset_resolverÚvalidate_platform_toolsetsÚplatform_toolsetsrQ  rW  z(platform_toolsets validation skipped: %sN)
Úhermes_cli.toolset_validationrƒ  r„  ri  rR  r  re  rK  r’  r¢  )r;  rM  rƒ  r„  r5  r½  Ú_ts_val_errs   &&     r8   rf  rf  t  s‚   € ð	Nßdä Ó"ˆÙ+¨F¯J©JÐ7JÓ,KÑMcÐdjÓMkÖlˆAØ�JÕ×&Ñ& qÔ)ß‘5Ü˜˜q˜c�lÖ#ó møô ô NÜ�‰Ð?À×MÒMûðNús   ‚AA+ ÁA+ Á+BÁ6BÂBc                ó^   € V ^8„  d   QhR\         R\        \         ,          R\         R\        /# )r3   Úheadingr  Úquestionr4   )rD   r  r6   )r7   s   "r8   r9   r9   ƒ  s,   € ÷ 
ñ 
œð 
¤T¬#¥Yð 
¼#ð 
Ä$ñ 
r:   c                ó®   € \        V 4       V F  p\        RV 24       K  	  \        4        \        V4      '       g   \        R4       R# \        4        R# )zUPrint a bulleted offer list and ask; False (with the "set later" hint) when declined.u       â€¢ z1  Set later with: hermes config set <key> <value>FT)re  rJ  )r‰  r  rŠ  Úitems   &&& r8   Ú_offer_listr�  ƒ  sF   € ä	ˆ'„NÛˆÜ�˜˜ÐÖ ñ ä	„GÜ�x× Ò ÜÐAÔBÙÜ	„GÙr:   c                ób   € V ^8„  d   QhR\         R\         R\        \        \        3,          RR/# )r3   rm  rl  r;  r4   N)r  rj  rD   r   )r7   s   "r8   r9   r9   �  s4   € ÷ ñ ¬cð ¼sð ÌTÔRUÔWZÐRZÍ^ð Ð`dñ r:   c                óð  € \        4       p\        V ^,           V^,           4       F(  pVP                  \        P	                  V. 4      4       K*  	  \        V4       Uu. uF2  p\        V4      '       d   K  V\        9   g   K#  V\        V,          3NK4  	  ppV'       dJ   \        R\        V4       R2V UUu. uF  w  rWV RVP	                  RR4       2NK  	  uppR4      '       g   R# V Fz  w  rW\        RVP	                  RV4       24       VP	                  R	4      '       d   \        R
VR	,           24       \        WWRVP	                  RV4       R2V4       \        4        K|  	  R# u upi u uppi )zSInteractively offer env vars that are NEW since the user's previous config version.ú
  z$ new optional key(s) in this update:õ    â€” r�  rL   z  Configure new keys? [y/N]: Nr!  r\  r]  r:  z (Enter to skip): )rà  r%  r  ÚENV_VARS_BY_VERSIONrR  rã  r	  rÓ  r�  r  re  rA  )rm  rl  r;  Únew_var_namesÚverr  Únew_and_unsetr{  s   &&&     r8   rg  rg  �  s]  € ä›€MÜ�[ 1•_ j°1¥nÖ5ˆØ×ÑÔ0×4Ñ4°S¸"Ó=Ö>ñ 6ô ˜=Ô)óBá)ˆDÜ˜T×"ô 	(à'+Ô/@Ñ'@ô 	(ˆÔ  Õ&Ó'Ù)ð ð B÷ ¤Ø
Œs�=Ó!Ð"Ð"FÐGÙGTÔUÁ}¹¸ˆDˆ6��t—x‘x ¨rÓ2Ð3Ó	4Á}ÒUØ'÷!)ò !)ñ 	Û#‰
ˆÜ��4—8‘8˜M¨4Ó0Ð1Ð2Ô3Ø�8‰8�E�?Š?ÜÐ'¨¨U­ }Ð5Ô6Ü˜T¨2¨d¯h©h°xÀÓ.FÐ-GÐGYÐ)ZÐ\cÔdÜŽó $ùòBùó 	Vs   ÁE-Á6E-ÂE-Â8"E2c                óŽ   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        \        \        3,          RR/# )r3   rs  r;  r4   Nr†  )r7   s   "r8   r9   r9   ¦  s<   € ÷ ñ ´4¼¼SÄ#¸X½Õ3Gð ÔRVÔWZÔ\_ÐW_ÕR`ð Ðeiñ r:   c                ó0  € \        R\        V 4       R2V  Uu. uF+  q"R,           RVR,           RVP                  RR4       R	2NK-  	  upR
4      '       g   R# \        4       p ^ RIHp V  EF  pVP                  RR4      pV'       d   RV R	2MRp\        RVR,           V R24      P                  4       ;'       g    \        T;'       g    R4      pV'       dQ   \        W4 RVR,           2V4       VR,          P                  VR,          4       \        RVR,           RV 24       M6VR,          P                  RVR,           RVP                  RR4       R24       \        4        EK  	  \        V4       R# u upi   \         d    Rp EL*i ; i)zRPrompt for skill-declared settings that are missing/empty and persist the answers.r�  z! skill setting(s) not configured:r¥   r‘  r�  z (from skill: Úskillr9  Ú)z#  Configure skill settings? [y/N]: N)r›  zskills.configrŽ  rL   z (default: r!  r:  r[  r�  rP  r?  ú = rQ  r^  u    â€” skill 'Ú?z' may ask for it later)r�  r  rR  ri  r¡  r›  rK  r   r-  rD   r;  r  re  r8  )	rs  r;  r¦  r5  r›  rŸ  rŽ  Údefault_hintr  s	   &&       r8   rj  rj  ¦  s‘  € äØ
ŒsÐ'Ó(Ð)Ð)JÐKÙauÓvÑauÐ\]ˆe�Hˆ:�U˜1˜]Õ+Ð,¨N¸1¿5¹5ÀÈ)Ó;TÐ:UÐUVÓ	WÑauÑvØ-÷/ò /ñ 	ÜÓ€Fð.Ý9ô $ˆØ—'‘'˜) RÓ(ˆß3:˜ W I¨QÑ/ÀˆÜ˜R  H¥˜¨|¨n¸BÐ?Ó@×FÑFÓH×^Ð^ÌCÐPW×P]ÐP]Ð[]ÓL^ˆßÜ˜Ð"7°q¸¸U½¸Ð EÀuÔMØ�NÕ#×*Ñ*¨3¨u­:Ô6Ü�L  U¥ ¨C°¨wÐ7Õ8à�JÕ×&Ñ&Ø˜3˜u�:˜, l°3·7±7¸7ÀCÓ3HÐ2IÐI_Ð`ôbä�ñ $ô �vÖùò) 	wøô ô .Ø-Óð.ús   ˜1E?
Á$F ÆFÆFc                ó<   € V ^8„  d   QhR\         R\         R\         /# )r3   ÚrawÚoverrider4   ©rj  )r7   s   "r8   r9   r9   Á  s!   € ÷ ñ œTð ¬Tð ´dñ r:   c                óJ  € \         P                  ! V4      pV P                  4        Fx  w  r4W29  d   \         P                  ! V4      W#&   K%  \        VP	                  V4      \
        4      '       g   KL  \        V\
        4      '       g   Kd  \        WBV,          4      W#&   Kz  	  V# )uF  Merge *override* over *raw* for partial ``save_config`` writes.
Omitted top-level sections are preserved; shared dict sections deep-merge so one nested key
can change without dropping siblings on disk. Key REMOVALS are not supported here â€”
migrations go through ``_persist_migration`` with a full ``read_raw_config()`` dict.)ÚcopyÚdeepcopyr  rŽ  rR  rj  Ú_deep_merge)rž  rŸ  Úresultr¥   r  s   &&   r8   Ú_merge_partial_saver¦  Á  sr   € ô
 �]Š]˜8Ó$€FØ—i‘i–k‰
ˆØÔÜŸ-š-¨Ó.ˆF‹KÜ˜Ÿ
™
 3›¬×.Ô.´:¸eÄT×3JÔ3JÜ% e°C­[Ó9ˆF‹Kñ	 "ð
 €Mr:   c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r3   ÚbaserŸ  r4   r   )r7   s   "r8   r9   r9   Ï  s!   € ÷ ñ ”dð ¤dð ¬tñ r:   c                ó"  € V P                  4       pVP                  4        Fj  w  r4\        VP                  V4      \        4      pV'       d-   \        V\        4      '       d   \        W#,          V4      W#&   KX  V'       d   Vf   Kf  WBV&   Kl  	  V# )a’  Recursively merge *override* into *base*: dict-over-dict recurses (so overriding one leaf
keeps sibling defaults), and ``None`` over a dict section is ignored.

An empty section key in config.yaml (``terminal:`` with no value) parses as YAML ``None``; treating that
as an override would replace the entire default dict with ``None`` and crash every downstream consumer
that expects a mapping (#58277).
)r¢  r  rŽ  rR  rj  r¤  )r¨  rŸ  r¥  r¥   r  Ú	over_dicts   &&    r8   r¤  r¤  Ï  sj   € ð �Y‰Y‹[€FØ—n‘nÖ&‰
ˆÜ˜vŸz™z¨#›´Ó5ˆ	ßœ E¬4×0Ò0Ü% f¥k°5Ó9ˆF‹Kß ¤Ø�3‹Kñ 'ð €Mr:   c                ó^   € V ^8„  d   QhR\         R\        R\        \         \        3,          /# )r3   ÚcfgÚdotted_keysr4   )rj  rà  r  )r7   s   "r8   r9   r9   á  s*   € ÷ ñ œDð ¬sð ´u¼TÄ3¸YÕ7Gñ r:   c                óÔ   € \        4       pV FV  pVP                  R4      Ev rE\        V .VO5!  p\        V\        4      '       g   K;  WV9   g   KC  We VP                  V4       KX  	  W3# )zçRemove dotted leaf keys from *cfg* in place -> ``(cfg, keys_actually_present)``.
``save_config`` drops managed-scope leaves this way so a bulk write never persists a user
value that would lose to the managed layer on the next load.r�  )rà  rž  r�  rŽ  rj  rõ  )r¬  r­  ÚstrippedÚdottedr?  Úleafrÿ  s   &&     r8   Ú_strip_dotted_keysr²  á  s`   € ô “E€HÛˆØŸ™ cÓ*‰ˆÜ�sÐ%˜WÓ%ˆÜ�dœD×!Ô! d¦lØ�
Ø�L‰L˜Ö ñ ð ˆ=Ðr:   z\${([^}]+)}c                óF   € V ^8„  d   QhR\         R\        \         ,          /# ©r3   r  r4   ©rD   r   )r7   s   "r8   r9   r9   ò  s   € ÷ ñ œ#ð ¤(¬3¥-ñ r:   c                óÔ   €  ^ RI HpHp T! 4       f    \        P
                  P                  T 4      # T! T 4      #   \         d#    \        P
                  P                  T 4      u # i ; i)u`  Resolve the env var behind a ``${VAR}`` / ``${env:VAR}`` ref â€” plain ``os.environ`` outside
a profile secret scope (legacy behavior for the default profile).

Inside a scope (a multiplexed gateway turn, a secondary profile's config load, a cron job) the read goes
through ``agent.secret_scope.get_secret`` so the ref resolves against *that* profile's ``.env``: under
multiplexing a miss is a miss, never another profile's ``os.environ`` value (#84079 â€” every profile
"had" the default profile's ``${MATRIX_ACCESS_TOKEN}`` and fanned out). Same policy as
``gateway.config._getenv`` and ``get_env_value``.
)Úcurrent_secret_scopeÚ
get_secret)Úagent.secret_scoper·  r¸  rK  rv  rw  rR  )r  r·  Ú_get_secrets   &  r8   Ú_env_ref_lookupr»  ò  sW   € ð$ßVñ ÓÒ%Ü�z‰z�~‰~˜dÓ#Ð#Ù�tÓÐøô	 ô $Ü�z‰z�~‰~˜dÓ#Ò#ð$ús   ‚: º*A'Á&A'c                óD   € V ^8„  d   QhR\         P                  R\        /# )r3   Úmr4   )ÚreÚMatchrD   )r7   s   "r8   r9   r9     s   € ÷ ñ œŸ™ð ¤cñ r:   c                ó®  € V P                  ^ 4      pV P                  ^4      P                  4       p\        V4      pVfX   VP                  R4      '       g?   \	        V4      '       d.   \
        P                  RWP                  R^4      ^ ,          4       V# \        V4      pVe   V# VP                  R4      '       d   \
        P                  RW4       V# )aw  Expand one ``${VAR}`` (legacy bare name) or ``${env:VAR}`` (Cursor-style SecretRef).
Other SecretRef sources (``file:``, ``bitwarden:``, ``vault:``...) are NOT resolved here:
external backends inject their values into the environment at startup (the ``secrets:``
block), so a config ref only ever needs the env shape. Unresolved refs stay verbatim so
callers can detect them.úenv:u¬   Config ref %r uses source %r which is not resolvable in config.yaml â€” external secret sources inject env vars at startup, so reference the variable as ${env:NAME} insteadÚ:zTConfig ref %r: %s is not set (check ~/.hermes/.env); keeping the literal placeholder)	Úgroupr-  Ú_env_ref_var_namer³   Ú_is_non_env_secret_refr’  r¼  rž  r»  )r½  rž  Úinnerr  r1  s   &    r8   Ú_env_expand_matchrÇ    sÀ   € ð �'‰'�!‹*€CØ�G‰G�A‹J×ÑÓ€EÜ˜UÓ#€DØ‚|Ø×Ñ ×'Ò'Ô,BÀ5×,IÒ,IÜ�N‰NðLð —[‘[  aÓ(¨Õ+ô	-ð
 ˆ
Ü
˜$Ó
€CØ
‚Øˆ
Ø×Ñ˜×ÒÜ�‰ð.Ø/2ô	:ð €Jr:   c                ó0   € V ^8„  d   QhR\         R\        /# ©r3   Úrefr4   rC   )r7   s   "r8   r9   r9      s   € ÷ Kñ K¤ð K¬ñ Kr:   c                óN   € RV 9   ;'       d    \         P                  ! RV 4      RJ# )zWTrue for a SecretRef body with a non-``env`` source (``bitwarden:FOO``, ``vault:...``).rÂ  z^[a-z][a-z0-9_-]*:N)r¾  r°   ©rÊ  s   &r8   rÅ  rÅ     s%   € à�#‰:×JÐJœ"Ÿ(š(Ð#8¸#Ó>ÀdÐJÐJr:   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# rÉ  rµ  )r7   s   "r8   r9   r9   %  s   € ÷ ñ œ3ð ¤8¬C¥=ñ r:   c                óÆ   € V P                  4       p V P                  R4      '       d'   V \        R4      R P                  4       ;'       g    R# \        V 4      '       d   R# V # )zTEnv-var name a ``${...}`` body reads, or None for a non-env source / empty ``env:``.rÁ  N)r-  r³   r  rÅ  rÌ  s   &r8   rÄ  rÄ  %  sQ   € à
�)‰)‹+€CØ
‡~�~�f×ÒØ”3�v“;�<Ð ×&Ñ&Ó(×0Ð0¨DÐ0Ü˜c×"Ò"ÙØ€Jr:   c                óf  € \        V \        4      '       d   \        P                  \        V 4      # \        V \
        4      '       d/   V P                  4        UUu/ uF  w  rV\        V4      bK  	  upp# \        V \        4      '       d   V  Uu. uF  p\        V4      NK  	  up# V # u uppi u upi )z]Recursively expand ``${VAR}`` / ``${env:VAR}`` in string values (keys/non-strings untouched).)	rŽ  rD   Ú_ENV_REF_REÚsubrÇ  rj  r  Ú_expand_env_varsr  )Úobjr,  r¦  rŒ  s   &   r8   rÒ  rÒ  /  sŒ   € ä�#”s×ÒÜ�‰Ô0°#Ó6Ð6Ü�#”t×ÒØ36·9±9´;Ô?±;©4¨1�Ô# AÓ&Ò&±;Ò?Ð?Ü�#”t×ÒÙ36Ó7±3¨4Ô  Ö&±3Ñ7Ð7Ø€Jùó @ùâ7s   ÁB(ÂB.c                ó~  € Vf   / p\        V \        4      '       d=   \        P                  V 4       F!  p\	        V4      pVf   K  \        V4      W&   K#  	  V# \        V \        4      '       d%   V P                  4        F  p\        WA4       K  	  V# \        V \        4      '       d   V  F  p\        WQ4       K  	  V# )u<  Map each env-sourced ``${...}`` ref in *obj* to its current value.
Stored with cached ``load_config()`` results so a cache hit can detect that the expansion was
made against a different environment (load before ``load_hermes_dotenv()``, in-process
rotation) â€” file mtime/size alone cannot see either.

See #58514.
)
rŽ  rD   rÐ  ÚfindallrÄ  r»  rj  r¥  Ú_env_ref_snapshotr  )rÓ  Úsnapshotrž  r  r  rŒ  s   &&    r8   rÖ  rÖ  :  s¨   € ð ÒØˆÜ�#”s×ÒÜ×&Ñ& sÖ+ˆCÜ$ SÓ)ˆDØÔÜ!0°Ó!6�“ñ ,ð €Oô 
�Cœ×	Ò	Ø—Z‘Z–\ˆEÜ˜eÖ.ñ "ð
 €Oô 
�Cœ×	Ò	ÛˆDÜ˜dÖ-ñ à€Or:   c                óô   € \        V \        4      '       g   R# / pV  FW  p\        V\        4      '       d&   \        VP                  R4      \        4      '       g    R# VR,          pW19   d    R# W!V&   KY  	  V# )zHReturn a name-indexed dict only when all items have unique string names.Nr  )rŽ  r  rj  rR  rD   )r  ÚindexedrŒ  r  s   &   r8   Ú_items_by_unique_namerÚ  R  se   € ä�eœT×"Ò"ÙØ€GÛˆÜ˜$¤×%Ò%¬Z¸¿¹ÀÓ8HÌ#×-NÒ-NÚØ�F�|ˆØŒ?ÚØ�‹ñ ð €Nr:   c                óX  € \        V \        4      '       dN   \        V\        4      '       d8   \        P                  V4      '       d   WV39   g   \	        V4      V 8X  d   V# V # \        V \
        4      '       d|   \        V\
        4      '       df   V P                  4        UUu/ uFH  w  r4T\        YAP                  V4      \        V\
        4      '       d   VP                  V4      MR4      bKJ  	  upp# \        V \        4      '       Ed   \        V\        4      '       dø   \        V 4      p\        V4      p\        V4      pVec   Ve_   V  Uu. uFQ  p\        Y†P                  VP                  R4      4      Ve!   VP                  VP                  R4      4      MR4      NKS  	  up# \        V 4       U	Uu. uFX  w  r˜\        TV	\        V4      8  d	   W,          MR\        V\        4      '       d   V	\        V4      8  d	   W),          MR4      NKZ  	  upp	# V # u uppi u upi u upp	i )z¬Restore raw ``${VAR}`` templates where the value is otherwise unchanged, so persisting a
loaded (expanded) config never writes the plaintext secret back to ``config.yaml``.Nr  )rŽ  rD   rÐ  ÚsearchrÒ  rj  r  Ú_preserve_env_ref_templatesrR  r  rÚ  rØ  r  )
r  rž  Úloaded_expandedr¥   r  Úcurrent_by_nameÚraw_by_nameÚloaded_by_namerŒ  Úindexs
   &&&       r8   rÝ  rÝ  a  sõ  € ô �'œ3×Ò¤J¨s´C×$8Ò$8¼[×=OÑ=OÐPS×=TÒ=TØ˜OÐ,Ô,Ô0@ÀÓ0EÈÔ0PØˆJØˆä�'œ4× Ò ¤Z°´T×%:Ò%:ð
 &Ÿm™mœoô	/ñ .‘
�ð Ô,Ø—w‘w˜s“|Ü,6°Ì×,MÒ,M�×#Ñ# CÔ(ÐSWóYò Yñ .ò	/ð 	/ô �'œ4× Ó ¤Z°´T×%:Ò%:ô 0°Ó8ˆÜ+¨CÓ0ˆÜ.¨Ó?ˆØÒ&¨;Ò+Bñ
 $ó	%ñ $�Dô ,ØŸ/™/¨$¯(©(°6Ó*:Ó;Ø<JÒ<V�N×&Ñ& t§x¡x°Ó'7Ô8Ð\`öbñ $ñ	%ð %ô  )¨Ô1ô3ñ  2‘�ô (ØØ#¤c¨#£hÔ.�–
°Dä˜o¬t×4Ò4¸ÄÀ_ÓAUÔ9Uð  Ö&àöñ  2ò3ð 	3ð €Nùó7/ùò%ùó
3s   Â#AHÅAH!Æ7AH&c                ó‚   € V ^8„  d   QhR\         \        \        3,          R\        \        \        R3,          ,          /# )r3   r5  r4   .)rj  rD   r   rà  r  )r7   s   "r8   r9   r9   ˆ  s/   € ÷ ñ ¤4¬¬S¨¥>ð ´c¼%ÄÀSÀ½/Õ6Jñ r:   c                óD   aa€ \        4       oR VV3R lloS! V R4       S# )z©Leaf paths explicitly present in a RAW (un-normalized) config, so values injected by
normalisation are never mistaken for user-set ones. Feeds ``_strip_default_values``.c                óN   € V ^8„  d   QhR\         R\        \        R3,          RR/# )r3   r  r'  .r4   N©r   r  rD   )r7   s   "r8   r9   Ú,_explicit_config_paths.<locals>.__annotate__�  s)   € ÷ ñ ”Sð ¤¤c¨3 h¥ð °Dñ r:   c                 óÀ   <€ \        V \        4      '       d,   V P                  4        F  w  r#S! W1V3,           4       K  	  R # V'       d   SP                  V4       R # R # r+  )rŽ  rj  r  rõ  )r  r'  r¥   ÚchildÚ_walkÚpathss   &&  €€r8   rê  Ú%_explicit_config_paths.<locals>._walk�  sC   ø€ Ü�eœT×"Ò"Ø#Ÿk™kžm‘
�Ù�e S F�]Ö+ó ,çØ�I‰I�dŽOñ r:   r=   )rà  )r5  rê  rë  s   &@@r8   Ú_explicit_config_pathsrí  ˆ  s'   ù€ ô #&£%€E÷ñ ñ 
ˆ&�"ÔØ€Lr:   c          
      óô   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\        \        \
        \        R3,          ,          ,          R\         \        \        3,          /# )r3   r5  rŠ  Úpreserve_keys.r4   )rj  rD   r   r   rà  r  )r7   s   "r8   r9   r9   ˜  sV   € ÷ 3ñ 3Ü””c��Nð3Ü&*¬3´¨8¥nð3äœC¤¤c¨3 h¥Õ0Õ1ð3ä=AÄ#ÄsÀ(½^ñ3r:   c                ó’   aaa€ R0\        S;'       g    R4      ,          o\        4       oR VVV3R lloS! WR4      pVSJ d   / # T# )a!  Return *config* without keys whose values match *defaults*.
Paths in *preserve_keys* (explicitly present in the user's raw config) are always kept even
when equal to the default. Dicts whose every child is stripped are removed entirely so
default-only subtrees never bloat ``config.yaml``.c                ób   € V ^8„  d   QhR\         R\         R\        \        R3,          R\         /# )r3   r  rŽ  r'  .r4   ræ  )r7   s   "r8   r9   Ú+_strip_default_values.<locals>.__annotate__£  s6   € ÷ Eñ E”cð E¤Cð E¬u´S¸#°X­ð EÄ3ñ Er:   c                 óð  <€ VS	9   d   \         P                  ! V 4      # \        V \        4      '       dš   V '       d’   \        V\        4      '       d   TM/ pV P	                  4        UUu/ uF%  w  rEVS! WSP                  V4      W$3,           4      bK'  	  pppVP	                  4        UUu/ uF  w  rEVSJg   K  WEbK  	  upp;'       g    S# W8X  d   S# \         P                  ! V 4      # u uppi u uppi r+  )r¢  r£  rŽ  rj  r  rR  )
r  rŽ  r'  Údefault_dictr,  r¦  r¯  Ú_stripÚdroppedrï  s
   &&&    €€€r8   rõ  Ú%_strip_default_values.<locals>._strip£  sÍ   ø€ Ø�=Ô Ü—=’= Ó'Ð'Ü�eœT×"Ò"§uÜ&0°¼$×&?Ò&?™7ÀRˆLØSX×S^ÑS^ÔS`ÔaÑS`É4È1˜™6 !×%5Ñ%5°aÓ%8¸$À½+ÓFÒFÑS`ˆHÑaØ%-§^¡^Ô%5ÔJÑ%5™T˜Q¸À'Ð9I”D�A’DÑ%5ÒJ×UÐUÈgÐUØÔ*ˆwÐD´·²¸eÓ0DÐDùó bùÛJs   Á*+C,Â+
C2Â:C2)rb  r=   )rà  Úobject)r5  rŠ  rï  r¯  rõ  rö  s   &&f @@r8   Ú_strip_default_valuesrù  ˜  sR   ú€ ð *Ð*¬S°×1DÐ1DÀ"Ó-EÕE€Mä‹h€G÷Eò Eñ �f¨Ó+€HØ˜WÓ$ˆ2Ð2¨(Ð2r:   c                óR   € V ^8„  d   QhR\         R\        \        \        3,          /# )r3   Úraw_defaultr4   ræ  )r7   s   "r8   r9   r9   °  s"   € ÷ 0ñ 0¬Cð 0´E¼#¼s¸(µOñ 0r:   c                óz  € \        V \        4      '       d‚   \        V P                  R4      ;'       g    R4      P	                  4       pV P                  R4      ;'       g    V P                  R4      p\        T;'       g    R4      P	                  4       V3# \        T ;'       g    R4      P	                  4       R3# )z™Canonicalize ``model.default``/``model.model`` -> ``(model, provider)``; a dict value pairs
the model string with the provider it must be routed through.ÚproviderrL   r  rŽ  )rŽ  rj  rD   rR  r-  )rû  rý  r  s   &  r8   Úsplit_model_config_defaultrþ  °  s”   € ô �+œt×$Ò$Ü�{—‘ zÓ2×8Ð8°bÓ9×?Ñ?ÓAˆØ—‘ Ó(×FÐF¨K¯O©O¸IÓ,FˆÜ�E—K�K˜RÓ ×&Ñ&Ó(¨(Ð3Ð3Ü�×!Ð!˜rÓ"×(Ñ(Ó*¨BÐ/Ð/r:   c                ót   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          /# r  r   )r7   s   "r8   r9   r9   º  s.   € ÷ Rñ R¤t¬C´¨H¥~ð R¼$¼sÄC¸x½.ñ Rr:   c                óB  a a€ S P                  R4      o\        S\        4      '       d   SP                  R4      MRpVRJ;'       d    \        V\        4      '       * ;'       gž    \        S\        4      ;'       d†    SP                  R4      ;'       gm    SP                  R4      ;'       gT    SP                  R4      ;'       g;    \        ;QJ d    V3R lR 4       F  '       g   K   RM	  R	M! V3R lR 4       4      p\        ;QJ d    V 3R
 lR 4       F  '       g   K   RM	  R	M! V 3R
 lR 4       4      pV'       g   V'       g   S # \        S 4      o S P                  R4      p\        V\        4      '       d   \        V4      MV'       d   RV/M/ pVS R&   R Fÿ  pVP                  V4      p\        V\        4      '       g   K,  VP                  R4      ;'       g    VP                  R4      p\        VP                  R4      ;'       g    R4      P                  4       p\        T;'       g    R4      P                  4       WE&   V'       g   K·  \        VP                  R4      ;'       g    R4      P                  4       p	V	'       d
   V	R8X  g   Kú  W„R&   EK  	  R FI  p
S P                  V
4      pV'       d   VP                  V
4      '       g   W´V
&   S P                  V
R4       KK  	  VP                  R4      e   \        VP                  R4      4      VR&   S P                  R4      VP                  R4      3 F*  pV'       g   K  VP                  R4      '       d   K&  WÄR&   K,  	  S P                  RR4       VP                  RR4       VP                  R4      ;'       g    VP                  R4      pVP                  R4      '       g   V'       d   WÔR&   VP                  R4      '       d%   VP                  RR4       VP                  RR4       S # )uy  Canonicalize the ``model`` section at the single load/save chokepoint.
Root-level ``provider``/``base_url``/``context_length`` (older layouts) are moved under
``model`` only when the corresponding ``model.*`` key is empty â€” never overriding. ``api_base``
(the OpenAI-SDK/LiteLLM name users reach for) is an alias for ``base_url``; the runtime reads
only ``model.base_url``. A dict-valued ``default``/``model``/``name`` is flattened so no reader
sees a nested dict, and the id is canonicalized to ``default``.

Also aliases ``api_base`` â†’ ``base_url`` (issue #8919). ``api_base`` is the intuitive name OpenAI-SDK /
LiteLLM users reach for, and ``hermes config set`` blindly accepts any dotted key â€” so
``model.api_base`` got written, confirmed, and then silently ignored by the runtime resolver (which
reads only ``model.base_url``), causing requests to fall back to OpenRouter. We migrate the alias to the
canonical key (fallback-only â€” never override an explicit ``base_url``) and drop the alias so it can't
confuse later loads.
Finally, canonicalizes the model-id key to ``model.default`` (issue #34500). The runtime resolver and
~14 other readers select the chat model via ``model.default``; ``model.model`` was already aliased
inline at some sites but ``model.name`` was not, so a custom-provider config like ``model: {name: <id>,
provider: <custom>}`` resolved to an empty model and the API request went out with ``model=`` (HTTP 400
from OpenAI-compatible backends) â€” while display paths (``hermes status``/``dump``) read ``name`` and
*showed* the model, making the failure silent. Normalizing here (the single load/save chokepoint) means
every reader, present and future, sees a populated ``default`` and the stale alias is migrated out of
config.yaml on the next save. Precedence: ``default`` > ``model`` > ``name`` (never overrides an
explicit ``default``, so existing configs are unaffected).
r  rý  NÚapi_baser  c              3   ób   <"  € T F$  p\        SP                  V4      \        4      x € K&  	  R # 5ir+  )rŽ  rR  rj  )r  r,  Úmodel_ins   & €r8   r!  Ú-_normalize_root_model_keys.<locals>.<genexpr>Ø  s%   øé € Ð[Ñ>Z¸”:˜hŸl™l¨1›o¬t×4Ð4Ó>Zùs   ƒ,/rŽ  TFc              3   óF   <"  € T F  pSP                  V4      x € K  	  R # 5ir+  )rR  )r  r,  r5  s   & €r8   r!  r  Ù  s   øé € ÐaÑ*` Q�6—:‘:˜a—=�=Ó*`ùs   ƒ!rH  rL   Úauto)rŽ  r  r  )rý  rH  Úcontext_lengthr  )rý  rH  r  )rR  rŽ  rj  rD   Úanyr-  rI  rã  )r5  Úmodel_providerÚneeds_model_workÚhas_rootr  rø  rù  Ú_nested_modelÚ_nested_providerÚ_outer_providerr¥   Úroot_valÚ	alias_valÚaliasr  s   f             @r8   Ú_normalize_root_model_keysr  º  s8  ù€ ð0 �z‰z˜'Ó"€HÜ1;¸HÄd×1KÒ1K�X—\‘\ *Ô-ÐQU€NØ&¨dÐ2×ZÐZ¼:ÀnÔVYÓ;ZÔ7Z÷ ^ð ^Ü�8œTÓ"÷ 	]ð 	]Ø�L‰L˜Ó$÷ \ð \Ø�|‰|˜GÓ$÷\ð \Ø(0¯©°VÓ(<÷\ð \ç‹sÔ[Ñ>ZÓ[�s�sŠsÔ[Ñ>ZÓ[Ó[ð	 ÷
 ‹sÔaÑ*`Óa�s�sŠsÔaÑ*`ÓaÓa€Hß×,Øˆä�&‹\€FØ�J‰J�wÓ€EÜ% e¬T×2Ò2ŒD�ŒKÏe¸ÀEÑ8JÐY[€EØ€Fˆ7�Oó -ˆØ�y‰y˜‹ˆÜ�dœD×!Ô!Ø ŸH™H WÓ-×DÐD°·±¸)Ó1DˆMÜ" 4§8¡8¨JÓ#7×#=Ð#=¸2Ó>×DÑDÓFÐÜ˜m×1Ð1¨rÓ2×8Ñ8Ó:ˆE‰KßÑÜ"% e§i¡i°
Ó&;×&AÐ&A¸rÓ"B×"HÑ"HÓ"J�ß&¨/¸VÖ*CØ(8˜*Ô%ñ -ó :ˆØ—:‘:˜c“?ˆß˜EŸI™I cŸNšNØ!�#‰JØ�
‰
�3˜Öñ	 :ð ‡y�y�ÓÒ(Ü.¨u¯y©y¸Ó/DÓEˆˆjÑà—j‘j Ó,¨e¯i©i¸
Ó.CÓDˆ	ß‰9˜UŸY™Y z×2Ô2Ø )�*Óñ Eð ‡J�Jˆz˜4Ô Ø	‡I�Iˆj˜$Ôð �I‰I�gÓ×3Ð3 %§)¡)¨FÓ"3€EØ�9‰9�Y×Ò§EØ ˆiÑØ‡y�y�×ÒØ�	‰	�'˜4Ô Ø�	‰	�&˜$Ôà€Mr:   c                ót   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          /# r  r   )r7   s   "r8   r9   r9     s*   € ÷ 
ñ 
¬¬S´#¨X­ð 
¼4ÄÄSÀ½>ñ 
r:   c                óâ   € \        V 4      p \        V P                  R4      ;'       g    / 4      pRV 9   d   RV9  d   V R,          VR&   V'       g   RV 9   d   WR&   V P                  RR4       V # )z§Move legacy root-level ``max_turns`` under ``agent``; the schema default is injected only
when the user set max_turns somewhere (so save_config can otherwise omit it).ÚagentÚ	max_turnsN)rj  rR  rI  )r5  Úagent_configs   & r8   Ú_normalize_max_turns_configr    sj   € ô �&‹\€FÜ˜Ÿ
™
 7Ó+×1Ð1¨rÓ2€LØ�fÔ °LÔ!@Ø$*¨;Õ$7ˆ�[Ñ!ß�w &Ô(Ø&ˆw‰Ø
‡J�Jˆ{˜DÔ!Ø€Mr:   c                ót   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          /# r  r   )r7   s   "r8   r9   r9     s.   € ÷ Kñ K¤¤c¬3 h¥ð K´D¼¼c¸µNñ Kr:   c                ó*   € \        \        V 4      4      # )zUThe load/save normalization pipeline: max_turns relocation, then model-section canon.)r  r  )r5  s   &r8   Ú_canonicalize_configr    s   € ä%Ô&AÀ&Ó&IÓJÐJr:   Únoner}  c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r3   rž  rŽ  r4   ©r   r  )r7   s   "r8   r9   r9   +  s!   € ÷ 1ñ 1œCð 1¬#ð 1Ìñ 1r:   c                óZ  € V e   \        V \        4      '       d   V# \        V \        \        34      '       d   \        V 4      pMˆ\        V \        4      '       dG   V P                  4       P                  4       pV'       g   V# V\        9   d   \        #  \        V4      pM,\        P                  R\        V 4      P                  W4       V# V^ 8:  d   \        # T#   \         dD     \        \        T4      4      p L1  \         d    \        P                  RY4       Tu u # i ; ii ; i)zRNormalize a raw ``agent.max_turns`` value into an int iteration cap (always >= 1).u7   resolve_turn_limit: unparseable value %r â†’ default %du;   resolve_turn_limit: unsupported type %s (%r) â†’ default %d)rŽ  r6   r  ÚfloatrD   r-  r.  Ú_UNLIMITED_SPELLINGSÚTURN_LIMIT_UNLIMITEDr±   r’  r¢  r�  rP   )rž  rŽ  r   Úss   &&  r8   Úresolve_turn_limitr$  +  sù   € ð ‚{”j ¤d×+Ò+ØˆÜ�#œœU�|×$Ò$Ü�‹H‰Ü	�Cœ×	Ò	Ø�I‰I‹K×ÑÓˆßØˆNØÔ$Ô$Ü'Ð'ð	Ü�A“‰Aô 	�‰ÐRÔTXÐY\ÓT]×TfÑTfÐhkÔuØˆØ#$¨¤6ÔÐ0¨qÐ0øô ô 	ðÜœ˜a›“M’øÜô Ü—‘ÐVÐX[ÔeØ”ðúð	ús*   ÂC ÃD*Ã(C>Ã>#D&Ä!D*Ä%D&Ä&D*rŽ  c                ó€   € V ^8„  d   QhR\         \        \        \        3,          ,          R\        R\        R\        /# )r3   r¬  rá  rŽ  r4   r  )r7   s   "r8   r9   r9   G  s5   € ÷ ñ ”œ$œs¤C˜x�.Õ)ð ´#ð Äð Ìsñ r:   c               óœ   € \        V \        4      '       g   V# T pV F+  p\        V\        4      '       d   WC9  d   Vu # W4,          pK-  	  V# )zûTraverse nested dict keys safely, returning ``default`` on any miss.
Explicit ``None`` values are returned as-is (``dict.get`` semantics: ``default`` only when the
key is absent). Named ``cfg_get`` to avoid shadowing the ubiquitous ``cfg_path`` local.)rŽ  rj  )r¬  rŽ  rá  rÿ  r¥   s   &$*  r8   r�  r�  G  sI   € ô �cœ4× Ò ØˆØ€DÛˆÜ˜$¤×%Ò%¨¬ØŠNØ�yŠñ ð €Kr:   c          	      óŽ   € V ^8„  d   QhR\         R\        \        R3,          R\        \        \         \        3,          ,          /# )r3   Úpath_keyÚ	cache_key.r4   )rD   r  r   r   rj  )r7   s   "r8   r9   r9   U  s;   € ÷ ñ ¤Cð ´E¼#¸s¸(µOð ÌÔQUÔVYÔ[^ÐV^ÕQ_ÕH`ñ r:   c                ó‚   € \         P                  V 4      pVe&   VR\        V4       V8X  d   V\        V4      ,          # R# )zìPure lookup: the cached raw config for ``path_key`` if its signature equals ``cache_key``,
else ``None``. Shared by the lock-free fast path and the locked re-check of
``_read_raw_config_impl`` so the predicate cannot drift between them.N)Ú_RAW_CONFIG_CACHErR  r  )r(  r)  Úcacheds   && r8   Ú_raw_config_cache_hitr-  U  s>   € ô ×"Ñ" 8Ó,€FØÒ˜f _¤c¨)£nÐ5¸ÔBØ”c˜)“nÕ%Ð%Ùr:   c                ó\   € V ^8„  d   QhR\         \        \        \        3,          ,          /# r2   r  )r7   s   "r8   r9   r9   _  s    € ÷ 
$ñ 
$¤¬$¬s´C¨x­.Õ!9ñ 
$r:   c                 ót   €  ^ RI Hp  V ! 4       #   \         d   pTP                  R8w  d   h  Rp?R# Rp?ii ; i)zÒA safe worker's frozen config, or None. Install-time loads run from ``hermes_cli`` alone
(the installer's completion step ships no ``agent`` package), and without ``agent`` there
is no worker policy to consult.)Úworker_config_snapshotr  N)Úagent.safe_worker_policyr0  ÚModuleNotFoundErrorr  )r0  r—  s     r8   Ú_worker_config_snapshotr3  _  s9   € ðÝCñ
 "Ó#Ð#øô	 ô Ø�8‰8�wÔØÝûðús   ‚ �7š2²7c                óR   € V ^8„  d   QhR\         R\        \        \        3,          /# ©r3   Úwant_deepcopyr4   rN  )r7   s   "r8   r9   r9   l  s"   € ÷ /6ñ /6¬Dð /6´T¼#¼s¸(µ^ñ /6r:   c           
      óÞ  € \        4       pVe   V#  \        4       p\        VP                  4       4      p\	        \        V4      V4      pVe!   V '       d   \        P                  ! V4      # T#  \        ;_uu_ 4        \        4       p \        VP                  4       4      p\        T4      p\	        Yc4      pTe+   T '       d   \        P                  ! T4      MTuuR R R 4       #  \        TRR7      ;_uu_ 4       p\        T4      ;'       g    / pR R R 4       \!        X\"        4      '       g6   \        \%        R\'        T4      P(                   24      R7      uuR R R 4       # \*        P,                  ! TR 4       \        P                  ! T4      p	. TOT	N5\.        T&   T '       d   TMT	uuR R R 4       #   \         d     ELUi ; i  \         d    / u uuR R R 4       # \         d!   p\        TR7      u R p?uuR R R 4       # R p?ii ; i  + '       g   i     EL; i  \         d,   p\        Y%4       \        TR7      u R p?uuR R R 4       # R p?ii ; i  + '       g   i     R # ; i)N©r“  r)  r*  ú&top-level YAML must be a mapping, got )r3  r…  r%   Ústatr-  rD   r¢  r£  rK  Ú_CONFIG_LOCKrz  r/  r*   rx  r$   r.   rŽ  rj  r�  r�  rP   r'   rI  r+  )
r6  r×  r”  r)  Úhitr¤  r(  r|  r•  Úcached_copys
   $         r8   Ú_read_raw_config_implr>  l  sô  € Ü&Ó(€HØÒØˆðÜ%Ó'ˆÜ" ;×#3Ñ#3Ó#5Ó6ˆ	Ü#¤C¨Ó$4°iÓ@ˆØŠ?ß)6”4—=’= Ó%Ð?¸CÐ?ð ÷
 
ŽÜ%Ó'ˆð	-Ü& {×'7Ñ'7Ó'9Ó:ˆIô �{Ó#ˆÜ# HÓ8ˆØŠ?ß)6”4—=’= Ô%¸C÷ 
Šð	-Ü�k¨K×8Õ8¸AÜ% aÓ(×.Ð.¨B�÷ 9ô ˜$¤×%Ò%Ü#¬)Ð6\Ô]aÐbfÓ]g×]pÑ]pÐ\qÐ4rÓ*sÔt÷- 
Šô. 	×"Ò" 8¨TÔ2ô —m’m DÓ)ˆØ&?¨	Ð&?°;Ñ&?Ô˜(Ñ#ß$‰t¨+÷9 
Šøô ô Úðûô !ô 	Ø‰I÷ 
Šô ô 	-Ü#¨!Ô,Ô,÷ 
Šûð	-ú÷ 9×8Ð8ûäô 	-Ü& {Ô6Ü#¨!Ô,Ô,÷' 
Šûð"	-ú÷# 
�ˆúsÔ   ’AF6 ÁF6 Á,F6 Á=IÂ	GÂ"!IÃIÃ'H"Ã<H	ÄH"ÄA IÅ%AIÆ(IÆ6GÇGÇHÇIÇ!HÇ*HÇ+HÇ6HÇ7IÈHÈIÈHÈH"ÈIÈH"È"IÈ-IÉIÉIÉIÉIÉI,	c                óF   € V ^8„  d   QhR\         \        \        3,          /# r2   r   )r7   s   "r8   r9   r9   ž  s   € ÷ 5ñ 5œœc¤3˜h�ñ 5r:   c                 ó   € \        RR7      # )zÙRead config.yaml as-is (no defaults merged, no migration); ``{}`` if missing/unparseable.
Cached on the file signature (mtime_ns, size, ino, ctime_ns); returns a deepcopy since callers mutate before ``save_config()``.T©r6  ©r>  r=   r:   r8   ri  ri  ž  s   € ô !¨tÔ4Ð4r:   c                óh   € V ^8„  d   QhR\         \        ,          R\        \        \        3,          /# ©r3   r”  r4   ©r   r	   rj  rD   r   )r7   s   "r8   r9   r9   ¤  s&   € ÷ 2ñ 2¤h¬t¥nð 2ÄÄSÌ#ÀXÅñ 2r:   c                ó  € V f   \        4       p  \        V RR7      ;_uu_ 4       p\        V4      ;'       g    / pRRR4       \	        X\
        4      '       d   T# / #   + '       g   i     L*; i  \         d    / u # i ; i)uÜ   Read a user ``config.yaml`` EXACTLY as written (no defaults/overlay/expansion, no cache).
ONLY legal for write-back round-trips and raw-file diagnostics â€” behavioral reads must use
load_config()/load_config_readonly().Nr)  r*  )r…  rx  r$   rz  rŽ  rj  )r”  r|  r•  s   &  r8   Úread_user_config_rawrG  ¤  sr   € ð ÒÜ%Ó'ˆðÜ�+¨×4Õ4¸Ü! !Ó$×*Ð*¨ˆD÷ 5ô ˜d¤D×)Ò)ˆ4Ð1¨rÐ1÷	 5×4ûäô ØŠ	ðús-   �A0 ¥A»A0 ÁA-	Á(A0 Á-A0 Á0B Á?B c                óF   € V ^8„  d   QhR\         \        \        3,          /# r2   r   )r7   s   "r8   r9   r9   ²  s   € ÷ 6ñ 6¤$¤s¬C x¥.ñ 6r:   c                 ó   € \        RR7      # )a  ``read_raw_config()`` without the per-call deepcopy, for callers that ONLY READ.
**Mutating the result corrupts the in-process cache for every subsequent caller.** Meant for
per-turn policy checks that were paying a full config deepcopy 2-3x per agent turn.FrA  rB  r=   r:   r8   Úread_raw_config_readonlyrJ  ²  s   € ô !¨uÔ5Ð5r:   c                óh   € V ^8„  d   QhR\         \        ,          R\        \        \        3,          /# rD  rE  )r7   s   "r8   r9   r9   ¹  s+   € ÷ $ñ $´h¼tµnð $ÔPTÔUXÔZ]ÐU]ÕP^ñ $r:   c           
     ó`  € V f/   \        4       pVe   \        P                  ! V4      # \        4       p  V P	                  4         \        T RR7      ;_uu_ 4       p\        T4      pRRR4       Xf   / # \!        T\"        4      '       gq   \%        R
\'        T4      P(                   24      p\        YRR7       \        T R\'        T4      P(                   2T\        P                  ! \        4       R	7      4      ThT#   \
         d    / u # \         d   p\        T RT\        4      ThRp?ii ; i  + '       g   i     LÒ; i  \         d   p\        T RT\        4      ThRp?i\         d?   p\        YRR7       \        T RT\        P                  ! \        4       R	7      4      ThRp?ii ; i)uÂ  Refuse to replace an existing config.yaml that cannot be read or parsed; return the mapping.
Guards two collapse-to-empty failure modes that would let a read-then-write caller silently
wipe user overrides: an unreadable file (permissions / broken mount) and an unparseable or
non-mapping root â€” bare-``except`` loaders treat both as ``{}``, so a subsequent write would
replace the recoverable file with only the caller's partial dict. Fails closed.Nzcannot be accessedr)  r*  zcannot be readzrefuse-write©Úfallbackzhas a formatting error)Úbackupsr9  z7must start with settings names, but its top level is a )r3  r¢  r£  r…  r:  rz  r/  r-   r(   rx  r$   rK  r.   r)   r7   r+   rŽ  rj  r�  r�  rP   )r”  r×  r—  r|  Úloadeds   &    r8   Ú$require_readable_config_before_writerQ  ¹  s‘  € ð ÒÜ*Ó,ˆØÒä—=’= Ó*Ð*Ü%Ó'ˆð]Ø×ÑÔðsÜ�+¨×4Õ4¸Ü# AÓ&ˆF÷ 5ð ‚~Øˆ	Ü�fœd×#Ò#ÜÐ@ÄÀfÃ×AVÑAVÐ@WÐXÓYˆÜ" ;¸nÕMÜØÐRÔSWÐX^ÓS_×ShÑShÐRiÐjØ”×!Ò!Ô*>Ó*@ÔAóCàHKð	Lð €Møô- ô ØŠ	Üô ]Ü Ð-AÀ3Ì
ÓSÐY\Ð\ûð]ú÷ 5×4ûäô YÜ Ð-=¸sÄJÓOÐUXÐXûÜô sÜ" ;¸nÕMÜØÐ1°3¼	×8HÒ8HÔQeÓQgÔ8hójØorð	sûðsúsk   ´C< ÁE ÁD0Á&E Ã<D-ÄD-ÄD-ÄD(Ä(D-Ä0E 	Ä;E Å E ÅF-ÅE!Å!F-Å.F-Å/9F(Æ(F-c          	      ó¼   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          R\        \        R3,          R\        \        ,          /# )r3   rÇ  Úproposedrº  .r4   )rj  rD   r   r  r  )r7   s   "r8   r9   r9   à  sH   € ÷ ñ Ü”3œ�8�nðÜ(,¬S´#¨X­ðÜ@EÄcÈ3ÀhÅðä	Œ#…Yñr:   c                ó¦  € . pV P                  4        Fº  w  rE. VO\        V4      N5pWA9  d#   VP                  RP                  V4      4       K=  W,          p\	        V\
        4      '       g   K]  \	        V\
        4      '       d   VP                  \        WWV4      4       K�  V'       g   Kš  VP                  RP                  V4      4       K¼  	  V# )a¨  Mapping paths that *proposed* would delete by omission from *existing*.

The round-trip writer recurses through mappings, so the completeness check must recurse too:
checking top-level key counts still lets a partial ``plugins: {...}`` payload erase sibling
settings inside that section. Replacing a non-empty mapping with a scalar/list is likewise a
deletion of that mapping's children and is reported at the mapping path.
r�  )r  rD   r  r  rŽ  rj  rh  Ú_omitted_config_paths)rÇ  rS  rº  Úomittedr¥   Ú	old_valuer'  Ú	new_values   &&&     r8   rU  rU  à  s¡   € ð €GØ"Ÿ.™.Ö*‰ˆØ"�Ð"œ˜S›Ñ"ˆØÔØ�N‰N˜3Ÿ8™8 D›>Ô*ÙØ•Mˆ	Ü�i¤×&Ô&Ü˜)¤T×*Ò*Ø—‘Ô4°YÈ4ÓPÖQß‘Ø—‘˜sŸx™x¨›~Ö.ñ +ð €Nr:   Úextra_content_on_createc          
      ó„   € V ^8„  d   QhR\         R\        \        \        3,          R\        R\
        \        ,          RR/# )r3   r”  r•  Úallow_omissionsrY  r4   N)r	   rj  rD   r   r6   r   )r7   s   "r8   r9   r9   ù  sI   € ÷ cñ cÜðcÜ!¤#¤s (�^ðcÜAEðcä%¤c�]ðcð 
ñcr:   c               óL  € ^ RI Hp \        W4       V'       g�   \        V 4      p\	        WQ4      pV'       dc   RP                  VR,          4      p\        V4      ^8”  d   VR\        V4      ^,
           R2,          p\        RV 24      p\        V RVR4      VhV! WVR	7       R
# )z[Shared comment-preserving config writer; omission policy is selected by the public wrapper.)Úatomic_roundtrip_yaml_saveú, :Né   Nz, +z morezomitted config paths: z)would lose settings omitted by this writeznPass the complete current config, or use atomic_config_replace() only when deletion by omission is deliberate.©rY  N)	Úutilsr]  r,   rQ  rU  r  r  r±   r-   )	r”  r•  r[  rY  r]  rÇ  rV  Úshownr—  s	   &&$$     r8   Ú_write_config_staterc  ù  s£   € õ
 1ä˜Ô*ßÜ7¸ÓDˆÜ'¨Ó7ˆßØ—I‘I˜g c�lÓ+ˆEÜ�7‹|˜bÔ Ø˜3œs 7›|¨bÕ0Ð1°Ð7Õ7�ÜÐ5°e°WÐ=Ó>ˆCÜ#ØØ;Øð6ó	ð ðñ ˜{ÐJa×br:   c                óx   € V ^8„  d   QhR\         R\        \        \        3,          R\        \        ,          RR/# ©r3   r”  r•  rY  r4   N©r	   rj  rD   r   r   )r7   s   "r8   r9   r9     s?   € ÷ 
cñ 
cÜð
cÜ!¤#¤s (�^ð
cÜIQÔRUÍð
cà	ñ
cr:   c               ó"   € \        WRVR7       R# )ap  Persist config without allowing an incomplete mapping to delete existing settings.

Values explicitly present in *data* may change, but every existing mapping path must remain.
Use ``atomic_config_replace`` for a deliberate full-state replacement where omitted keys are
meant to be deleted. Both paths retain the unreadable-file guard and ruamel comment preservation.
F©r[  rY  N©rc  ©r”  r•  rY  s   &&$r8   Úatomic_config_writerk    s   € ô Ø¨5ÐJa÷cr:   c                óx   € V ^8„  d   QhR\         R\        \        \        3,          R\        \        ,          RR/# re  rf  )r7   s   "r8   r9   r9      s?   € ÷ bñ bÜðbÜ!¤#¤s (�^ðbÜIQÔRUÍðbà	ñbr:   c               ó"   € \        WRVR7       R# )zYPersist the complete desired config state; omitted mapping keys are deliberately deleted.Trh  Nri  rj  s   &&$r8   Úatomic_config_replacern     s   € ô Ø¨4ÐI`÷br:   c                óF   € V ^8„  d   QhR\         \        \        3,          /# r2   r   )r7   s   "r8   r9   r9   (  s   € ÷ 1ñ 1”Tœ#œs˜(•^ñ 1r:   c                 ó   € \        RR7      # )a  Load the merged configuration (DEFAULT_CONFIG + config.yaml + managed scope, env-expanded).
Cached on the file signature; returns a deepcopy since most call sites mutate the result.
Read-only hot paths should use ``load_config_readonly()`` to skip the deepcopy.TrA  ©Ú_load_config_implr=   r:   r8   r–  r–  (  s   € ô ¨4Ô0Ð0r:   c                óF   € V ^8„  d   QhR\         \        \        3,          /# r2   r   )r7   s   "r8   r9   r9   /  s   € ÷ 2ñ 2œd¤3¬ 8�nñ 2r:   c                 ó   € \        RR7      # )u   ``load_config()`` without the defensive deepcopy (~half of the 265us cache-hit cost).
**Mutating the returned dict (or any nested structure) corrupts the in-process cache for
every subsequent caller** â€” only for code paths that never write to the result.FrA  rq  r=   r:   r8   Úload_config_readonlyru  /  s   € ô ¨5Ô1Ð1r:   c                ó€   € V ^8„  d   QhR\         \        \        3,          R\        R\         \        \        3,          /# )r3   r£  r¥   r4   r   )r7   s   "r8   r9   r9   6  s1   € ÷ ñ œœc¤3˜h�ð ¬cð ´d¼3Ä¸8µnñ r:   c                ó`   € V P                  V4      p\        V\        4      '       g   / pW V&   V# )zTReturn ``parent[key]`` as a dict, replacing a missing or non-dict value with ``{}``.)rR  rŽ  rj  )r£  r¥   ré  s   && r8   Ú_ensure_dictrx  6  s-   € à�J‰J�s‹O€EÜ�eœT×"Ò"ØˆØˆs‰Ø€Lr:   rž  c          
      óL   € V ^8„  d   QhR\         R\         R\        R\        RR/# )r3   Úplatform_keyÚ	field_keyr  rž  r4   N©rD   r   r6   )r7   s   "r8   r9   r9   ?  s4   € ÷ ñ ÜðÜ"%ðÜ.1ðÜ;?ðØLPñr:   c               óˆ   € V'       d   \        4       M	\        4       p\        VR4      pV\        WP4      V&   \        V4       R# )zæPersist one scalar field under ``platforms.<platform_key>``.
``raw=True`` (CLI setup flows) edits only the user's raw file; dashboard routes use the
default loaded-config path to keep their profile-scoped ``load_config`` behavior.r©  N)ri  r–  rx  r³  )rz  r{  r  rž  r5  r©  s   &&&$  r8   Úwrite_platform_config_fieldr~  ?  s5   € ÷
 #&Œ_Ô¬;«=€FÜ˜V [Ó1€IØ7<„L�Ó)¨)Ñ4Ü�Ör:   rq  Ú	TERMINAL_c                ó0   € V ^8„  d   QhR\         R\        /# ©r3   r  r4   )r   rD   )r7   s   "r8   r9   r9   [  s   € ÷ Pñ Pœsð P¤sñ Pr:   c                 ó|   € \        V \        \        34      '       d   \        P                  ! V 4      # \        V 4      # r+  )rŽ  r  rj  r  r€  rD   ©r  s   &r8   Ú_terminal_env_valuer„  [  s*   € Ü *¨5´4¼°,× ?Ò ?Œ4�:Š:�eÓÐOÄSÈÃZÐOr:   c                ó<   € V ^8„  d   QhR\         R\        R\        /# ©r3   r¥   r  r4   r|  )r7   s   "r8   r9   r9   _  s&   € ÷ Sñ S¬cð S¼#ð SÄ$ñ Sr:   c                ór   € V R8H  ;'       d'    \        T;'       g    R4      P                  4       R9   '       * # )zAReturn whether a terminal config value owns its mirrored env var.ÚcwdrL   >   r�  rˆ  r  )rD   r-  )r¥   r  s   &&r8   Ú$_terminal_config_value_is_bridgeabler‰  _  s1   € à�u‘×QÐQ¤ U§[ [¨bÓ!1×!7Ñ!7Ó!9Ð=QÑ!QÔRÐRr:   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r3   Úterminal_configr4   )r   rà  rD   )r7   s   "r8   r9   r9   d  s"   € ÷ Mñ M´Cð M¼CÄ½Hñ Mr:   c           	     óâ   € \        V \        4      '       g   \        4       # \        P	                  4        UUu0 uF)  w  rW9   g   K  \        WV,          4      '       g   K'  VkK+  	  upp# u uppi )zFReturn env vars explicitly owned by a raw ``terminal`` config section.)rŽ  rj  rà  ÚTERMINAL_CONFIG_ENV_MAPr  r‰  )r‹  r¥   Úenv_vars   &  r8   Úterminal_config_owned_env_varsr�  d  sh   € ä�o¤t×,Ò,Ü‹uˆô 4×9Ñ9Ô;ôMá;‰LˆCØÑ!ô 	ô 1°ÀcÕ6J×K÷ 	ˆÙ;òMð Mùó Ms   ¸
A+ÁA+Á!A+c                óF   € V ^8„  d   QhR\         R\        \         ,          /# r  rµ  )r7   s   "r8   r9   r9   o  s"   € ÷ hñ h¬ð h´¼#µñ hr:   c                óv   € V P                  R4      '       d"   \        P                  V \        R4      R 4      # R# )z;Return the env var mirrored by a ``terminal.*`` config key.z	terminal.N)r³   r�  rR  r  )r¥   s   &r8   Úterminal_config_env_var_for_keyr’  o  s6   € àBEÇ.Á.ÐQ\×B]ÒB]Ô"×&Ñ& s¬3¨{Ó+;Ð+<Ð'=Ó>ÐgÐcgÐgr:   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r3   rq  rˆ  r4   rC   )r7   s   "r8   r9   r9   t  s&   € ÷ ]ñ ]¤cð ]´ð ]¼ñ ]r:   c                ó¤   € T ;'       g    RP                  4       P                  4       R8H  ;'       d    VR8H  ;'       g    VP                  R4      # )z–Whether the remote SSH shell must expand *cwd* itself: ``~`` expanded on the Hermes host
would name the host/container home instead of the SSH user's.rL   ÚsshÚ~z~/)r-  r.  r³   )rq  rˆ  s   &&r8   Ú_is_ssh_remote_tilde_cwdr—  t  sE   € ð �MˆM�r× Ñ Ó"×(Ñ(Ó*¨eÑ3×\Ð\¸À¹×9[Ð9[ÀsÇ~Á~ÐVZÓG[Ð\r:   Úenvr5  rŸ  c          
      óð   € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          R\         \        ,          R\        \        \        3,          /# )r3   r˜  r5  rŸ  r4   )r   rj  rD   r   r6   )r7   s   "r8   r9   r9   z  sR   € ÷ 0ñ 0Ü”Tœ#œs˜(•^Õ$ð0Ü5=¼dÄ3ÌÀ8½nÕ5Mð0ä”t�nð0ä(,¬S´#¨X­ñ0r:   c                ó^  € V f   \         P                  MT p\        4       P                  R4      p\	        V\
        4      pV'       d   TM/ pVf   TMTpVe   TM	\        4       p\	        V\
        4      '       d   VP                  R/ 4      M/ p\	        V\
        4      '       g   V# Ve   VP                  4       MVP                  4       p	VP                  R4      VP                  R4      3p
Vf   RV9   g   V
RRR1,          p
\        V
^ ,          ;'       g    V
^,          ;'       g    R4      pV'       d   RV	9   d   RVR&   MRV9  d   R	V9   d   RMR
VR&   \        P                  4        F»  w  rÍWÈ9  d   K  WŒ,          p\        WÎ4      '       g   K(  VR8X  dj   \        T;'       g    R4      P                  4       p\	        V\        4      '       d1   \        W¿4      '       g    \         P                  P                  V4      pV'       d   WÉ9   g	   WÓ9  g   K®  \!        V4      W=&   K½  	  V# )aš  Bridge ``terminal.*`` config into the env vars terminal tools read.
``tools.terminal_tool`` is environment-driven because it also runs in child processes (TUI,
dashboard PTY, gateway workers); this gives those launch paths the same bridge as the CLI
without importing ``cli.py``. Explicit keys in the user's raw ``terminal`` section override
matching env values; merged defaults only backfill missing env vars.NÚterminalrq  r  rL   Údocker_imagerm  ÚTERMINAL_DOCKER_IMAGE_PINNEDÚTERMINAL_DOCKER_IMAGEÚ0rˆ  r#  )rv  rw  ri  rR  rŽ  rj  ru  rá  rD   r�  r  r‰  r-  r—  r'  Ú
expanduserr„  )r˜  r5  rŸ  ÚtargetÚraw_terminal_cfgÚfile_has_terminal_configÚshould_overrider¬  Úterminal_cfgÚexplicit_keysÚbackend_sourcesÚterminal_backendÚcfg_keyrŽ  r  Úraw_cwds   $$$             r8   Úapply_terminal_config_to_envr«  z  så  € ð š;ŒR�ZŠZ¨C€Fä&Ó(×,Ñ,¨ZÓ8ÐÜ)Ð*:¼DÓAÐß+CÑ'ÈÐØ2:Ò2BÑ.È€OàÒ&‰&Ô,@Ó,B€CÜ.8¸¼d×.CÒ.C�3—7‘7˜: rÔ*È€LÜ�l¤D×)Ò)Øˆð ,2Ò+=�L×%Ñ%Ô'ÐCS×CXÑCXÓCZ€MØ#×'Ñ'¨	Ó2°F·J±J¸~Ó4NÐO€OØÒ )Ð/?Ô"?Ø)©$¨B¨$Õ/ˆÜ˜?¨1Õ-×IÐI°ÀÕ1C×IÐIÀrÓJÐ÷
 ˜>¨]Ô:Ø14ˆÐ-Ò.Ø	'¨vÔ	5Ø8OÐSYÔ8Y±Ð_bˆÐ-Ñ.ä3×9Ñ9Ö;ÑˆØÔ&ÙØÕ%ˆÜ3°G×CÒCÙØ�eÔÜ˜%Ÿ+˜+ 2Ó&×,Ñ,Ó.ˆGÜ˜%¤×%Ò%Ô.FÐGW×.aÒ.aÜŸ™×*Ñ*¨5Ó1�ß Ô 8¸WÖ=RÜ1°%Ó8ˆF‹Oñ <ð €Mr:   c          
      óÎ   € V ^8„  d   QhR\         R\        \        \        \        \        \        \        3,          ,          \        \        \        R3,          ,          3,          /# )r3   r”  r4   .)r	   r  r   r  )r7   s   "r8   r9   r9   ­  sP   € ÷ Añ A¬ð A´´xÄÄcÌ3ÔPSÔUXÐFXÕ@YÕ7ZÔ\dÔejÔknÐpsÐksÕetÕ\uÐ7uÕ1vñ Ar:   c                ó^  €  V P                  4       p\        V4      p\        P                  ! 4       p V'       d   VR,          P                  4       MRpV'       d   \        V4      MRpVf
   VR8X  d   R# T. T;'       g    ROVO53#   \         d    Rp L{i ; i  \
         d    Rp LBi ; i)zûReturn ``(user_sig, cache_sig)`` for ``_LOAD_CONFIG_CACHE``.
The managed config file's signature is folded in ((0, 0, 0, 0) = none) so editing it invalidates
the merged result. ``cache_sig`` is None only when neither file exists (nothing to cache on).Nrƒ  )é    r®  r®  r®  )NN)r:  r%   rz  r   Úget_managed_dirr/  )r”  ÚstÚuser_sigÚmanaged_dirÚmstÚmanaged_sigs   &     r8   Ú_load_config_cache_sigrµ  ­  s·   € ðØ×ÑÓˆÜ8FÀrÓ8Jˆô  ×/Ò/Ó1€Kð#ß6Aˆ{˜]Õ*×0Ñ0Ô2Àtˆß-0”n SÔ)°lˆð Ò˜K¨<Ô7ØÐØÐ@˜×0Ð0 LÐ@°KÑ@Ð@Ð@øô ô ØŠðûô ô #Ø"Šð#ús-   ‚B	 ³B » B ÁB Â	BÂBÂB,Â+B,c                ó€   € V ^8„  d   QhR\         R\        R\        R\        \        \        \
        3,          ,          /# )r3   r”  r(  r—  r4   )r	   rD   rK  r   rj  r   )r7   s   "r8   r9   r9   Á  s<   € ÷ &ñ &¬4ð &¼3ð &ÔPYð &Ô^fÔgkÔloÔqtÐltÕguÕ^vñ &r:   c                ó¼  € \         P                  V4      pRpVfj   ^ RIHp ^ RIHp V! V 4      pVeR   \        \        P                  ! \        4      V4      p	V! W˜4       \        V	4      p
\        V
4      p\        V4      w  rLRp\        YVe   TMRR7       Vf   R# \        \        \        P                  ! V4      4      VR7      pVe   . VOVN/ N5\        V&   V# )	uj  Warn about a parse failure and return the last-known-good config, or None (-> defaults).
A parse failure must not silently replace the effective config with defaults â€” that drops
EVERY user override, including security-critical ``approvals.deny`` rules, when a gateway
user mid-edits config.yaml into broken YAML. Keep serving the last good config until fixed.zlast-known-goodN)Úload_newest_good_backup©Úapply_user_moa_presetszlast-known-good-backuprŠ  rM  r8  )Ú_LAST_EXPANDED_CONFIG_BY_PATHrR  r‘  r¸  r•  rº  r¤  r¢  r£  r´  r  rÒ  Ú_merge_managed_overlayr.   r*   Ú_LOAD_CONFIG_CACHE)r”  r(  Ú	cache_sigr—  ÚlkgrN  r¸  rº  Úraw_goodÚmerged_goodrÈ  Úexpanded_goodr~  Úlkg_copys   &&&&          r8   Ú_last_known_good_fallbackrÄ  Á  sÚ   € ô (×
+Ñ
+¨HÓ
5€CØ €HØ
‚{õ
 	FÝ@Ù*¨;Ó7ˆØÒÜ%¤d§m¢m´NÓ&CÀXÓNˆKÙ" ;Ô9Ü-¨kÓ:ˆJÜ,<¸ZÓ,HˆMÜ+¨MÓ:‰FˆCØ/ˆHÜØ¨sª¡8ÀJõPà
‚{Ùô  Ô 0´·²¸sÓ1CÓ DÈCÔP€HØÒð (B¨Ð'A°HÐ'A¸bÑ'AÔ˜8Ñ$Ø€Or:   c                ó–   € V ^8„  d   QhR\         \        \        3,          R\        \         \        \        3,          \        3,          /# )r3   Úexpandedr4   )rj  rD   r   r  )r7   s   "r8   r9   r9   ê  s8   € ÷ Wñ W¤T¬#¬s¨(¥^ð W¼¼dÄ3ÌÀ8½nÌcÐ>QÕ8Rñ Wr:   c                ó  € \         P                  ! 4       pV'       g   W3# \        V4      p\        VP	                  R4      \
        4      '       d   \        V4      pRVR,          /VR&   \        V \        V4      4      V3# )u‡  Apply the managed-scope overlay; returns ``(merged, managed_config_or_falsy)``.
Managed wins at the leaf and is applied AFTER user expansion so a user ``${VAR}`` cannot shadow
a managed literal: managed values expand only against the process environment. This
deliberately inverts the usual env-over-config precedence for the keys the managed layer pins
(docs/design/managed-scope.md Â§4.1).r  rŽ  )	r   Úload_managed_configr  rŽ  rR  rD   rj  r¤  rÒ  )rÆ  Úmanaged_configÚmanaged_normalizeds   &  r8   r¼  r¼  ê  s   € ô #×6Ò6Ó8€NßØÐ'Ð'ô 4°NÓCÐÜÐ$×(Ñ(¨Ó1´3×7Ò7Ü!Ð"4Ó5ÐØ'0Ð2DÀWÕ2MÐ&NÐ˜7Ñ#Ü�xÔ!1Ð2DÓ!EÓFÈÐVÐVr:   c          	      ót   € V ^8„  d   QhR\         R\        R\        \        \         \        3,          ,          /# )r3   r(  r¾  r4   )rD   r   r   rj  )r7   s   "r8   r9   r9   ü  s/   € ÷ ñ ¤Sð ´Sð ¼XÄdÌ3ÔPSÈ8ÅnÕ=Uñ r:   c                ór  € \         P                  V 4      pVe   Ve   VR,          V8w  d   R# V^,          p\        V\        4      '       dQ   \        VP                  \
        4      '       d1    \        V R4      ;_uu_ 4       pVP                  4        RRR4       R# \        V4      ^	8”  d
   V^	,          M/ p\        ;QJ d*    R VP                  4        4       F  '       d   K   RM	  RM! R VP                  4        4       4      '       d   V# R#   + '       g   i     R# ; i  \
         d    Tu # i ; i)a´  Lookup: the cached expanded config for ``path_key`` if its signature equals
``cache_sig`` AND every ``${VAR}`` it was expanded against still has the same value, else
``None``. Signatures matching is not enough: a load before load_hermes_dotenv() would otherwise
pin unexpanded literals (e.g. auxiliary.<task>.api_key) for the process lifetime (#58514).
Shared by the lock-free fast path and the locked re-check of ``_load_config_impl``.N:Né   NÚrbc              3   óB   "  € T F  w  r\        V4      V8H  x € K  	  R # 5ir+  )r»  ©r  r,  r¦  s   &  r8   r!  Ú)_load_config_cache_hit.<locals>.<genexpr>	  s   é € Ð
DÑ/C¡t qŒ?˜1Ó Ö"Ó/Cùs   ‚FT)r½  rR  rŽ  r*   Ú
read_errorr/  rx  Úreadr  Úallr  )r(  r¾  r,  r<  r|  Úenv_snapshots   &&    r8   Ú_load_config_cache_hitrÖ  ü  sé   € ô  ×#Ñ# HÓ-€FØ‚~˜Ò*¨f°R­j¸IÔ.EÙØ
��)€CÜ�#Ô'×(Ò(¬Z¸¿¹Ì×-PÒ-Pð	Ü�h ×%Ô%¨Ø—‘”÷ &áô !$ F£¨a¤�6˜!–9°R€Lß
ƒsÑ
D¨|×/AÑ/AÔ/CÓ
D‡s‡s‚sÑ
D¨|×/AÑ/AÔ/CÓ
D×DÒDØˆ
Ù÷ &Ö%áûÜô 	ØŠJð	ús0   Á.D& ÂDÂD& ÄD#	ÄD& Ä#D& Ä&D6Ä5D6c                óR   € V ^8„  d   QhR\         R\        \        \        3,          /# r5  rN  )r7   s   "r8   r9   r9   	  s&   € ÷ Vñ V¬ð V´´c¼3°hµñ Vr:   c                 ód  € \        4       pVe%   \        \        P                  ! \        4      V4      #  \        4       p\        V4      pV\        9   d=   \        V4      w  rE\        W54      pVe!   V '       d   \        P                  ! V4      # T# \        ;_uu_ 4        \        4        \        4       p\        T4      p\        T4      w  rx\        Y84      pTe+   T '       d   \        P                  ! T4      MTuuR R R 4       # \        P                  ! \        4      p	TeÔ    \        TRR7      ;_uu_ 4       p
\        T
4      ;'       g    / pR R R 4       \        P                   ! TR 4       RX9   dZ   \#        TP%                  R4      ;'       g    / 4      pTP%                  R4      f   TR,          TR&   YËR&   TP!                  RR 4       \        Y›4      p	^ RIHp T! Y›4       ^ RIHp T! TR4       \7        T	4      p\3        \5        T4      4      w  pp\        P                  ! T4      \8        T&   Te[   \        P                  ! T4      p\;        T4      pT'       d   \;        TT4       . TOTNTN5\        T&   T '       g   TuuR R R 4       # M\        P!                  TR 4       TuuR R R 4       #   \         d     EL2i ; i  + '       g   i     EL�; i  \         d·   p\/        Y#Y�4      pTe0   T '       d   \        P                  ! T4      MTu R p?uuR R R 4       # \1        \3        \5        \7        T	4      4      4      ^ ,          TR7      pTe   . TOTN/ N5\        T&   T '       d   \        P                  ! T4      MTu R p?uuR R R 4       # R p?ii ; i  + '       g   i     R # ; i)	Nr)  r*  r  r  r¹  rŠ  Úgoodr8  )r3  r¤  r¢  r£  r´  r…  rD   r½  rµ  rÖ  rK  r;  rÒ  rx  r$   r'   rI  rj  rR  r•  rº  r‘  r‹  rÄ  r*   r¼  rÒ  r  r»  rÖ  )r6  r×  r”  r(  r~  Úfast_sigr<  r±  r¾  r5  r|  Úuser_configÚagent_user_configrº  r‹  r¤  rÃ  rN  rÈ  rÆ  rÉ  r=  rÕ  s   $                      r8   rr  rr  	  s  € Ü&Ó(€HØÒÜœ4Ÿ=š=¬Ó8¸(ÓCÐCðÜ%Ó'ˆÜ�{Ó#ˆØÔ)Ô)Ü0°Ó=‰KˆAÜ(¨Ó<ˆCØŠß-:”t—}’} SÓ)ÐCÀÐC÷ 
ŽÜÔÜ%Ó'ˆÜ�{Ó#ˆä4°[ÓAÑˆä$ XÓ9ˆØŠ?ß)6”4—=’= Ô%¸C÷ 
Šô —’œ~Ó.ˆàÒðNÜ˜+°×<Õ<ÀÜ"0°Ó"3×"9Ð"9°r�K÷ =ä&×*Ò*¨8°TÔ:à +Ô-Ü(,¨[¯_©_¸WÓ-E×-KÐ-KÈÓ(LÐ%Ø(×,Ñ,¨[Ó9ÒAØ9DÀ[Õ9QÐ)¨+Ñ6Ø+< Ñ(Ø—O‘O K°Ô6ä$ VÓ9�ÝHÙ& vÔ;õ DÙ˜k¨6Ô2ô *¨&Ó1ˆ
Ü#9Ô:JÈ:Ó:VÓ#WÑ ˆ�.Ü26·-²-ÀÓ2IÔ% hÑ/ØÒ ô Ÿ-š-¨Ó1ˆKÜ,¨ZÓ8ˆLßÜ! .°,Ô?Ø+R¨YÐ+R¸Ð+RÀ\Ñ+RÔ˜xÑ(ç Ø"÷y 
Šðv !ô ×"Ñ" 8¨TÔ2à÷A 
Šøô ô ò 	ðú÷( =×<Ð<ûô& ô 
NÜ4°[ÈIÓY�ØÒ'ß6Cœ4Ÿ=š=¨Ô2ÈÔQ÷K 
ŠôP ,Ü*Ô+;Ô<PÐQWÓ<XÓ+YÓZÐ[\Õ]Ðefôh�àÒ(Ø3M°YÐ3MÀÐ3MÈ"Ñ3MÔ& xÑ0ß2?”t—}’} XÔ.ÀXÔM÷Y 
ŠûðD
Nú÷E 
�ˆús³   ´AJ4 Á8J4 ÂJ4 ÂANÃ"NÄNÄ#KÄ8K	ÅAKÆA$KÇ5BNÊNÊNÊ4KËKËKË	KËNË%NË=NÌNÌNÌ$A
NÍ/NÎNÎNÎNÎNÎN/	uþ  
# â”€â”€ Security â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
# Secret redaction is ON by default â€” strings that look like API keys,
# tokens, and passwords are masked in tool output, logs, and chat
# responses before the model or user ever sees them. Set redact_secrets
# to false to disable (e.g. when developing the redactor itself).
#
# security:
#   redact_secrets: true
u@  
# â”€â”€ Fallback Model â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
# Automatic provider failover when primary is unavailable.
# Uncomment and configure to enable. Triggers on rate limits (429),
# overload (529), service errors (503), or connection failures.
#
# Supported providers:
#   openrouter   (OPENROUTER_API_KEY)  â€” routes to any model
#   openai-codex (OAuth â€” hermes auth) â€” OpenAI Codex
#   nous         (OAuth â€” hermes auth) â€” Nous Portal
#   zai          (ZAI_API_KEY)         â€” Z.AI / GLM
#   kimi-coding  (KIMI_API_KEY)        â€” Kimi / Moonshot
#   kimi-coding-cn (KIMI_CN_API_KEY)   â€” Kimi / Moonshot (China)
#   minimax      (MINIMAX_API_KEY)     â€” MiniMax
#   minimax-cn   (MINIMAX_CN_API_KEY)  â€” MiniMax (China)
#   bedrock      (AWS IAM / boto3)     â€” AWS Bedrock (Converse API)
#
# For custom OpenAI-compatible endpoints, add base_url and key_env.
#
# fallback_model:
#   provider: openrouter
#   model: anthropic/claude-sonnet-4
c                ót   € V ^8„  d   QhR\         \        \        3,          R\         \        \        3,          /# r  r   )r7   s   "r8   r9   r9   ’	  s*   € ÷ ñ ¬¬c´3¨h­ð ¼DÄÄcÀ½Nñ r:   c           
     ó  € \         P                  ! 4       pV'       g   V # \        \        P                  ! V 4      V4      w  rV'       dC   \        R\        V4       RRP                  \        V4      4       2\        P                  R7       V # )z†Drop every leaf the managed layer pins (bulk safety net; single-key ``config set``
hard-rejects) and tell the user what was not saved.zNote: zD managed setting(s) were not saved (managed by your administrator): r^  rc  )r   Úmanaged_config_keysr²  r¢  r£  re  r  r  rã  rf  rg  )r5  Úmanaged_keysÚ	_strippeds   &  r8   Ú_strip_managed_keys_for_saverâ  ’	  sy   € ô !×4Ò4Ó6€LßØˆÜ*¬4¯=ª=¸Ó+@À,ÓOÑ€FßÜØ”S˜“^Ð$ð %0Ø04·	±	¼&ÀÓ:KÓ0LÐ/MðOÜUX×U_ÑU_õ	að €Mr:   c                óh   € V ^8„  d   QhR\         \        \        3,          R\        \        ,          /# )r3   rÈ  r4   )rj  rD   r   r   )r7   s   "r8   r9   r9    	  s&   € ÷ 	"ñ 	"¬T´#´s°(­^ð 	"ÄÌÅñ 	"r:   c                ó¶  € . pV P                  R4      ;'       g    / P                  R4      f   VP                  \        4       V P                  R/ 4      p\        V\        4      '       d   TMV.p\
        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       g   VP                  \        4       RP                  V4      ;'       g    R# )	zDCommented-out example blocks for features that are off/unconfigured.ÚsecurityÚredact_secretsNrê  c              3   ó¦   "  € T FG  p\        V\        4      ;'       d+    VP                  R 4      ;'       d    VP                  R4      x € KI  	  R# 5i)rý  r  N)rŽ  rj  rR  )r  r¤  s   & r8   r!  Ú/_commented_sections_for_save.<locals>.<genexpr>§	  s>   é € Ð`ÑU_ÐPQŒz˜!œTÓ"×KÐK q§u¡u¨ZÓ'8×KÐK¸Q¿U¹UÀ7»^ÔKÓU_ùs   ‚AžA·ATFrL   )rR  r  Ú_SECURITY_COMMENTrŽ  r  r  Ú_FALLBACK_COMMENTr  )rÈ  r  rè  Ú
fb_entriess   &   r8   Ú_commented_sections_for_saverì   	  s£   € à€EØ�‰�zÓ"×(Ð( b×-Ñ-Ð.>Ó?ÒGØ�‰Ô&Ô'Ø	�‰Ð(¨"Ó	-€BÜ! "¤d×+Ò+‘°"°€Jß‹3Ñ`ÑU_Ó`�3�3Š3Ñ`ÑU_Ó`×`Ò`Ø�‰Ô&Ô'Ø�7‰7�5‹>×!Ð!˜TÐ!r:   Ústrip_defaultsrï  Úmerge_existingc          
      ó°   € V ^8„  d   QhR\         \        \        3,          R\        R\        \
        \        \        R3,          ,          ,          R\        /# )r3   r5  rí  rï  .rî  )rj  rD   r   r6   r   rà  r  )r7   s   "r8   r9   r9   ¬	  sF   € ÷ ,<ñ ,<Ü””c��Nð,<Ü/3ð,<äœC¤¤c¨3 h¥Õ0Õ1ð,<äJNñ,<r:   c               ó$  € \         ;_uu_ 4        \        4       '       d   \        R4        RRR4       R# \        4       p\	        W@4       \        V 4      p \        4        \        V4      p^ RIH	p V! WV4      p \        V 4      pTpV'       d3   \        V\        V4      \        P                  \        V4      4      4      pV'       d8   \        V4      \!        T;'       g    R4      ,          p	\#        V\$        V	R7      p\'        WH\)        V4      R7       \+        V4       \,        P/                  \        V4      R4       \0        P2                  ! V4      \        \        V4      &   RRR4       ^ RIHp
 V
! XX4       R#   + '       g   i     L!; i)a€  Save configuration to ~/.hermes/config.yaml.
Schema defaults are not written unless the user explicitly set them (the path exists in the
raw config before normalisation), so config.yaml is never contaminated with defaults that
would hide future default changes. ``merge_existing`` deep-merges the on-disk raw config
under *config* so partial callers cannot drop sections they omitted.zsave configurationN)Úrebase_for_save)rï  r`  )Úrecord_config_savedr=   )r;  r  rh  r…  r,   râ  rÒ  rQ  Úhermes_cli.config_worker_saverñ  r  rÝ  r»  rR  rD   rí  rà  rù  r´  rn  rì  r«  r+  rI  r¢  r£  r7  rò  )r5  rí  rï  rî  r”  Ú_raw_for_pathsrñ  Úcurrent_normalizedrÈ  Úeffective_preserve_keysrò  s   &$$$       r8   r³  r³  ¬	  s8  € ÷ 
ŽÜ�<Š<ÜÐ.Ô/Ø÷ 
‰ô
 &Ó'ˆÜ˜KÔ0Ü-¨fÓ5ˆäÔô >¸kÓJˆÝAÙ  ¸ÓHˆä1°&Ó9ÐØ'ˆ
ßÜ4ØÔ0°Ó@Ü-×1Ñ1´#°kÓ2BÓCóEˆJ÷ ä&<¸^Ó&LÌsÐS`×SfÐSfÐdfÓOgÕ&gÐ#Ü.¨z¼>ÐYpÔqˆJä˜kÔOkÐlvÓOwÕxÜ�[Ô!Ü×Ñœc +Ó.°Ô5Ü:>¿-º-ÐHZÓ:[Ô%¤c¨+Ó&6Ñ7÷E 
õF UÙ˜Ð(:Ö;÷I 
�ús   �E?¶BE?Ã	E?Ã!BE?Å?F	c                óF   € V ^8„  d   QhR\         \        \        3,          /# r2   r‹  )r7   s   "r8   r9   r9   Û	  s   € ÷ 
)ñ 
)”$”sœC�x•.ñ 
)r:   c                 óJ   € \        4       e   / # ^ RIHp  V ! \        4       4      # )zÉLoad ~/.hermes/.env as a dict. Memoised inside ``load_env_file`` (``get_env_value()`` runs
hundreds of times per interactive menu render). Each assignment's value is opaque data for
boundary discovery.©Úload_env_file)r3  r¹  rú  rŸ  rù  s    r8   r.  r.  Û	  s"   € ô Ó Ò,Øˆ	Ý0áœ›Ó(Ð(r:   c                ó0   € V ^8„  d   QhR\         R\         /# )r3   Ú	raw_valuer4   rI   )r7   s   "r8   r9   r9   è	  s   € ÷ 	ñ 	¤ð 	¬ñ 	r:   c                ó   € ^ RI Hp V! V 4      # )u.  Frozen compat surface name (tests/compat/old_updater_surface.json).

Pre-PM updaters lazy-import ``hermes_cli.config._parse_env_value`` after the
checkout swap. The tokenizer moved to ``agent.secret_scope._parse_env_value``
(c849bc383a), so this forwards there â€” behavior-preserving by construction.
)Ú_parse_env_value)r¹  rþ  )rü  Ú_parses   & r8   rþ  rþ  è	  s   € õ >á�)ÓÐr:   c                ó   € V ^8„  d   QhRR/# r)  r=   )r7   s   "r8   r9   r9   ô	  s   € ÷  ñ  ˜dñ  r:   c                 ó    € ^ RI Hp  V ! 4        R# )z¢Drop the ``.env`` memo so the next ``load_env()`` sees a write even on coarse-mtime filesystems
(save_env_value / remove_env_value / sanitize_env_file call this).©Úinvalidate_env_file_cacheN)r¹  r  r  s    r8   Úinvalidate_env_cacher  ô	  s   € õ =áÖr:   c                ó0   € V ^8„  d   QhR\         R\         /# )r3   r$  r4   rL  )r7   s   "r8   r9   r9   ü	  s   € ÷ 
ñ 
œtð 
¬ñ 
r:   c                óÐ   € . pV  F]  pVP                  R4      pVP                  4       pTP                  V'       d   VP                  R4      '       d   TMTR,           4       K_  	  V# )a  Normalize .env line endings/whitespace without changing assignment semantics.
Content after the first ``=`` is opaque value data: a known variable name embedded in a value
must never be reinterpreted as another assignment, so concatenated lines stay on one line.z
rp  r"  )rƒ  r-  r  r³   )r$  Ú	sanitizedr}  rž  r¯  s   &    r8   Ú_sanitize_env_linesr  ü	  s\   € ð €IÛˆØ�k‰k˜&Ó!ˆØ—9‘9“;ˆà×Ñ§X°×1DÑ1DÀS×1IÒ1I™#ÈxÐ[_Õ_Ö`ñ	 ð
 Ðr:   c                ó$   € V ^8„  d   QhR\         /# r2   ©r  )r7   s   "r8   r9   r9   	
  s   € ÷ ñ œ3ñ r:   c            	     ó   € \        4       p V P                  4       '       g   ^ # \        V 4      ;_uu_ 4        \        V RRR7      ;_uu_ 4       pVP	                  4       pRRR4       \        X4      pW28X  d    RRR4       ^ # \        \        V4      \        V4      ,
          4      ;'       g    \        R \        W#4       4       4      p\        WRR7       RRR4       \        4        X#   + '       g   i     L”; i  + '       g   i     L/; i)z\Rewrite ~/.hermes/.env with normalized line formatting; returns the number of changed lines.r)  r<  ©r+  ÚerrorsNc              3   ó:   "  € T F  w  rW8w  g   K  ^x € K  	  R# 5i)é   Nr=   )r  ÚaÚbs   &  r8   r!  Ú$sanitize_env_file.<locals>.<genexpr>
  s   é € ð ADÙ8‘$�!¸A¹F�AŠAÓ8ùs   ‚
‘
F©Úpreserve_mode)rŸ  r¨  Ú_env_write_lockrx  Ú	readlinesr  Úabsr  ÚsumÚzipÚ_write_env_linesr  )Úenv_pathr|  Úoriginal_linesr  rn  s        r8   rc  rc  	
  sÔ   € ä‹~€HØ�?‰?×ÒÙÜ	˜×	"Õ	"Ü�( [¸×CÕCÀqØŸ[™[›]ˆN÷ Dä'¨Ó7ˆ	ØÔ&Ø÷ 
#Ñ	"ô ”C˜	“N¤S¨Ó%8Õ8Ó9÷ Dð D¼Sñ ADÜ˜nÔ8óADó >Dˆä˜¸EÕB÷ 
#ô ÔØ€L÷ D×Cú÷ 
#×	"ús*   ¶C=ÁC*	ÁC=ÂAC=Ã*C:Ã5C=Ã=D	c                ó0   € V ^8„  d   QhR\         R\        /# ©r3   r  r4   )r	   r  )r7   s   "r8   r9   r9   
  s   € ÷ 2ñ 2œdð 2¤tñ 2r:   c                óž   € \        V RRR7      ;_uu_ 4       p\        VP                  4       4      uuRRR4       #   + '       g   i     R# ; i)zsRead ``.env`` lines, normalized. Explicit UTF-8 (Windows defaults to cp1252) with BOM
tolerance (Notepad adds one).r)  r<  r  N)rx  r  r  )r  r|  s   & r8   Ú_read_env_linesr   
  s3   € ô 
ˆh °Y×	?Õ	?À1Ü" 1§;¡;£=Ó1÷ 
@×	?×	?Ó	?ús	   —;»A	c                ó0   € V ^8„  d   QhR\         R\        /# r  )r	   r   )r7   s   "r8   r9   r9   &
  s   € ÷ Jñ J¤Tð J¬cñ Jr:   c                óÄ   € \        V 4      p\        ;_uu_ 4        \        P                  V\        P
                  ! 4       4      uuRRR4       #   + '       g   i     R# ; i)z�Reentrancy tracker for one canonical ``.env`` path (mirrors auth's
``_auth_lock_holder_for``): multiplexed profiles each get their own tracker.N)rD   Ú_ENV_WRITE_LOCK_HOLDERS_GUARDÚ_ENV_WRITE_LOCK_HOLDERSr4  Ú	threadingÚlocal)r  r¥   s   & r8   Ú_env_write_lock_holderr'  &
  s9   € ô ˆh‹-€Cß	&Ö	&Ü&×1Ñ1°#´y·²Ó7HÓI÷ 
'×	&×	&Ó	&ús   š)AÁA	c                ó$   € V ^8„  d   QhR\         /# )r3   r  r   )r7   s   "r8   r9   r9   /
  s   € ÷ ñ œdñ r:   c              #  óÜ   "  € ^ RI Hp V! V P                  V P                  R,           4      \	        V 4      RRV  R24      ;_uu_ 4        Rx € RRR4       R#   + '       g   i     R# ; i5i)u<  Serialize a whole ``.env`` read-modify-write cycle (#77187).

``save_env_value`` / ``remove_env_value`` / ``sanitize_env_file`` read the file,
rewrite it in memory, then atomically replace it. Without a lock, two
concurrent writers (setup wizard + dashboard save, gateway + CLI) both
snapshot the pre-write file and the loser's replace silently drops the
winner's key. ``_CONFIG_LOCK`` cannot help: it guards in-memory config only.

Reuses ``hermes_cli.auth._file_lock`` (fcntl flock / msvcrt byte lock,
cross-process, reentrant per thread) rather than growing a second kernel-lock
implementation. The import is call-time: ``hermes_cli.auth`` imports this
module at import time, so a module-level import would be circular. Nothing
under this lock takes other locks, and the only nesting direction that exists
(credential_lifecycle takes ``_auth_store_lock`` around its own auth-store
writes, NOT around ``save_env_value``) keeps a single ordering â€” no cycle.
On a filesystem without flock the helper degrades to a depth-only guard
(same behavior as auth's locks), never to a crash.
)Ú
_file_lockz.lockg      .@z1Timed out waiting for the environment file lock (r™  N)Úhermes_cli.authr*  Ú	with_namer  r'  )r  r*  s   & r8   r  r  .
  s^   é € õ( +á	Ø×Ñ˜8Ÿ=™=¨7Õ2Ó3Ü˜xÓ(ØØ
;¸H¸:ÀQÐG÷	
õ 
ó 	÷
÷ 
÷ 
ò 
üs   ‚AA,Á	AÁ
A,ÁA)	Á#	A,c                ó@   € V ^8„  d   QhR\         R\        R\        RR/# )r3   r  r$  r  r4   N)r	   r  r6   )r7   s   "r8   r9   r9   M
  s(   € ÷ ñ œtð ¬Dð ÄDð ÈTñ r:   c               ó¾  € Rp V'       d/   \         P                  ! V P                  4       P                  4      MRp\	        V RRR7      w  rE \
        P                  ! VRRR7      ;_uu_ 4       pVP                  V4       VP                  4        \
        P                  ! VP                  4       4       RRR4       \        WP4       Te    \
        P                  ! Y4       R# \        T 4       R#   \         d     LÂi ; i  + '       g   i     LV; i  \         d+     \
        P                  ! T4       h   \         d     h i ; ii ; i  \         d     R# i ; i)zßAtomically replace ``.env`` (tmp file + fsync + rename).
``preserve_mode`` keeps the original file mode (e.g. 0640 for Docker volume mounts) instead of
letting ``_secure_file`` tighten to 0600; a new file is always secured.Nz.tmpz.env_)r»  rº  r½  r¹  r*  )r:  ÚS_IMODEÚst_moder/  r&   rv  rÃ  Ú
writelinesÚflushÚfsyncÚfilenor#   ÚBaseExceptionrÅ  r©  r«  )r  r$  r  Úoriginal_moderÈ  Útmp_pathr|  s   &&$    r8   r  r  M
  s  € ð €MðßANœŸš X§]¡]£_×%<Ñ%<Ô=ÐTXˆô " (°6À'ÔJ�L€BðÜ�YŠY�r˜3¨×1Õ1°QØ�L‰L˜ÔØ�G‰GŒIÜ�HŠH�Q—X‘X“ZÔ ÷ 2ô 	�xÔ*ð Ò ð	Ü�HŠH�XÖ-ô 	�XÖøô+ ô Ùðú÷ 2×1ûô
 ô ð	Ü�IŠI�hÔð 	øô ô 	ØØð	úðûô ô 	Úð	úsq   „C1 Œ0C1 Á!D Á.ADÂ4D ÃE Ã1C?Ã>C?ÄD	ÄD ÄE
Ä!D8Ä7E
Ä8EÅE
ÅEÅE
ÅEÅEc                ó<   € V ^8„  d   QhR\         R\         R\         /# r†  rI   )r7   s   "r8   r9   r9   l
  s!   € ÷ ñ ¤Sð ´ð ¼ñ r:   c                óÖ  € VP                  4       '       d   V# \        V4       UUu. uF.  w  r#\        V4      ^8”  g   K  RV RV: R\        V4      R R2NK0  	  pppVP                  RRR7      P	                  R4      p\        R	V  R
2RP                  R VR,           4       4      ,           \        V4      ^8”  d   RMR,           R,           \        P                  R7       V# u uppi )z­Strip non-ASCII characters from a credential (HTTP header values must be ASCII) and warn.
Lookalike glyphs typically come from copy-pasting out of a PDF or rich-text editor.z  position r[  z (U+Ú04Xr™  ÚasciiÚignore)r  z
  Warning: zÐ contains non-ASCII characters that will break API requests.
  This usually happens when copy-pasting from a PDF, rich-text editor,
  or web page that substitutes lookalike Unicode glyphs for ASCII letters.

r"  c              3   ó,   "  € T F
  pR V 2x € K  	  R# 5i)r!  Nr=   )r  r}  s   & r8   r!  Ú._check_non_ascii_credential.<locals>.<genexpr>y
  s   é € Ð:©M D�b˜˜•K«Mùs   ‚:Né   Nz
  ... and morerL   z‰

  The non-ASCII characters have been stripped automatically.
  If authentication fails, re-copy the key from the provider's dashboard.
rc  )
ÚisasciirØ  ÚordÚencodeÚdecodere  r  r  rf  rg  )r¥   r  r  r  Ú	bad_charsr  s   &&    r8   Ú_check_non_ascii_credentialrE  l
  sï   € ð ‡}�}‡‚ØˆäJSÐTYÔJZÔlÑJZÁÀÔ^aÐbdÓ^eÐhkÑ^kÔ<�;˜q˜c  B¡6¨¬c°"«g°c¨]¸!Ó<ÑJZ€IÑlØ—‘˜W¨X�Ó6×=Ñ=¸gÓF€Iä	Ø
˜�uð Yð 	Zð �)‰)Ñ:¨I°b®MÓ:Ó
:õ	;ô "% Y£°!Ô!3Ñ¸õ		=ð
Võ	Vô �Z‰Zõð Ðùó ms   §C%Á C%c                ó0   € V ^8„  d   QhR\         R\         /# r�  rI   )r7   s   "r8   r9   r9   �
  s   € ÷ ñ œCð ¤Cñ r:   c                ó  € V R8X  d   V # RV 9   gK   RV 9   gD   RV 9   g=   \         ;QJ d    R V  4       F  '       g   K   RM	  RM! R V  4       4      '       g   V # V P                  RR	4      P                  RR
4      pRV R2# )z°Quote .env values containing characters with special dotenv meaning. Any whitespace
(including internal runs) is quoted so ``set -a; . file`` word-splitting keeps paths intact.rL   rp  Ú"r{  c              3   ó@   "  € T F  qP                  4       x € K  	  R # 5ir+  )Úisspace)r  Úcs   & r8   r!  Ú#_quote_env_value.<locals>.<genexpr>†
  s   é € Ð?[ÑUZÐPQÇ	Á	ÇÀÓUZùs   ‚TFr  z\\z\")r  r<  )r  r:  s   & r8   Ú_quote_env_valuerM  �
  su   € ð �„{ØˆØ�5ŒL˜C 5œL¨C°5¬L¿C»CÑ?[ÑUZÓ?[¿C¿CºCÑ?[ÑUZÓ?[×<[Ò<[ØˆØ�m‰m˜D &Ó)×1Ñ1°#°uÓ=€GØˆwˆi�qˆ>Ðr:   c                ó^   € V ^8„  d   QhR\         R\         R\        \        ,          R\        /# )r3   r}  r¥   r£   r4   r¦   )r7   s   "r8   r9   r9   Œ
  s-   € ÷ :ñ :¤ð :¬#ð :¼hÄt½nð :ÔX\ñ :r:   c               ó
  € V P                  4       pVP                  R4      '       d   VR,          P                  4       pVP                  R4      w  rEpV'       g   R# \	        VP                  4       VR7      \	        WR7      8H  # )u“  True when a .env line assigns ``key`` â€” plain, ``export``-prefixed, or ``KEY = value``.
Must match exactly the shapes ``load_env()`` parses; otherwise a hand-added line is invisible
to save (duplicate appended) and remove (line survives -> the value resurrects on next load).

``load_env()`` accepts the bash-compatible ``export KEY=value`` form (#6659), so the writers must
recognise the same shape.
zexport :é   NNro  F)r£   )r-  r³   Úlstripry  r«   )r}  r¥   r£   r¯  Úassigned_keyÚ	separatorÚ_values   &&$    r8   Ú_env_line_defines_keyrU  Œ
  sw   € ð �z‰z‹|€HØ×Ñ˜9×%Ò%Ø˜B•<×&Ñ&Ó(ˆØ&.×&8Ñ&8¸Ó&=Ñ#€L˜VßÙô  Ø×ÑÓ¨ôä	˜cÔ	9ñ:ð :r:   c                óJ   € V ^8„  d   QhR\         R\        \         ,          RR/# ©r3   r¥   r  r4   Nrµ  )r7   s   "r8   r9   r9   ¢
  s%   € ÷  ñ  œCð  ¬´­ð  ¸$ñ  r:   c                ó\  €  ^ RI HpHp V! 4       V! 4       rT\	        V\
        4      '       d   V.M. pV'       g:   Ve   \	        V\
        4      '       d    VP                  \        P                  4       V F  pVf   VP                  V R4       K  WV &   K!  	  R#   \         d    RRrT L“i ; i)a#  Publish a just-persisted ``.env`` change to the live process.
Under a multiplexed gateway a routed profile's write must not land in the SHARED
``os.environ`` where every profile sees it; the installed scope mapping is updated instead so
same-turn reads see the change. All other callers keep the legacy ``os.environ`` publish.

``save_env_value`` / ``remove_env_value`` already target the right file (``get_env_path()`` honors the
profile-home override), but the in-process mirror historically went straight to ``os.environ``. See
#77490, #88441.
)r·  Úserves_routed_profileNF)
r¹  r·  rY  rK  rŽ  rj  r  rv  rw  rI  )r¥   r  r·  rY  ÚscopeÚroutedÚtargetsr¡  s   &&      r8   Ú_publish_env_valuer]  ¢
  sŽ   € ð$ßRá,Ó.Ñ0EÓ0Gˆvô $ E¬4×0Ò0ˆu‰g°b€Gß�u’}¬
°5¼$×(?Ò(?Ø�‰”r—z‘zÔ"ÛˆØŠ=Ø�J‰J�s˜DÖ!à�3‹Kó	 øô ô $Ø˜eŠvð$ús   ‚B ÂB+Â*B+c                óR   € V ^8„  d   QhR\         R\         R\        \         ,          /# ©r3   r¥   r\  r4   rµ  )r7   s   "r8   r9   r9   ¿
  s%   € ÷ 
ñ 
œ3ð 
¬ð 
´¼µñ 
r:   c                ó¨   € \        4       '       d   \        V RV  24      # \        P                  ! V 4      '       d   RV RV  R\	        R4       R2# R# )uï   The ``.env`` write-lock refusal for ``key``, or None when the write is allowed.
Two distinct locks: ``is_managed()`` (package-manager install) and the managed *scope*
(administrator-pinned env key â€” the managed .env wins at load anyway).r5  r^  z': it is managed by your administrator (rž  z) and cannot be changed.N)r  r`  r   Úis_env_managedÚ_managed_source©r¥   r\  s   &&r8   Úenv_write_refusalrd  ¿
  sb   € ô ‡|‚|Ü%¨¨°°#°Ð&7Ó8Ð8Ü×#Ò# C×(Ò(à�f�X˜Q˜s˜eÐ#JÌ?Ð[aÓKbÐJcð d%ð %ð	&ñ r:   c                ó<   € V ^8„  d   QhR\         R\         R\        /# r_  rC   )r7   s   "r8   r9   r9   Ì
  s!   € ÷ ñ œCð ¬ð ´ñ r:   c                óf   € \        W4      pV'       d   \        V\        P                  R7       VRJ# )z_Shared write-lock check for ``.env`` writers; prints the refusal and returns True when blocked.rc  N)rd  re  rf  rg  ©r¥   r\  Úrefusals   && r8   Ú_env_write_blockedri  Ì
  s(   € ä Ó,€GßÜˆgœCŸJ™JÕ'Ø˜$ÐÐr:   c                ó4   € V ^8„  d   QhR\         R\         RR/# ©r3   r¥   r\  r4   NrI   )r7   s   "r8   r9   r9   Ô
  s!   € ÷ "ñ "œcð "¬3ð "°4ñ "r:   c                óB   € \        W4      pV'       d   \        V4      hR# )a  Raise ``ValueError`` with the refusal when the ``.env`` write lock forbids ``key``.
``save_env_value`` / ``remove_env_value`` refuse by returning, which their caller cannot tell
from success, so a writer that also touches config.yaml or the credential pool must ask first.N)rd  r±   rg  s   && r8   Úrequire_env_writablerm  Ô
  s!   € ô   Ó,€GßÜ˜Ó!Ð!ñ r:   c                ó$   € V ^8„  d   QhR\         /# )r3   ÚfilenamerI   )r7   s   "r8   r9   r9   Ý
  s   € ÷ Lñ Lœcñ Lr:   c                óP   € \         P                  ! 4       pV'       d	   W,          # R# )z\``<managed dir>/<filename>`` for refusal messages, or a generic label without a managed dir.zthe managed scope)r   r¯  )ro  r²  s   & r8   rb  rb  Ý
  s!   € ä×/Ò/Ó1€Kß'2ˆKÕ"ÐKÐ8KÐKr:   c                ó0   € V ^8„  d   QhR\         R\         /# )r3   r¥   r  rI   )r7   s   "r8   r9   r9   ã
  s   € ÷ ñ œð ¤Cñ r:   c                óæ  a € \        S R4      '       d   R# \        S 4       VP                  RR4      P                  RR4      p\        S V4      p\	        4        \        4       p\        V4      ;_uu_ 4        VP                  4       '       d   \        V4      M. p\        V4      p\        V 3R l\        V4       4       R4      pVe   S  RV R2W5&   MRV'       d4   VR	,          P                  R4      '       g   VR	;;,          R,          uu&   VP                  S  RV R24       \        W#VP                  4       R7       RRR4       \        S V4       \!        4        R#   + '       g   i     L(; i)
zšSave or update a value in ~/.hermes/.env (also matching ``export KEY=`` lines, so a save
never appends a second line that a later delete would resurrect).rà  Nr"  rL   Úc              3   óT   <"  € T F  w  r\        VS4      '       g   K  Vx € K  	  R # 5ir+  )rU  )r  r  r}  r¥   s   &  €r8   r!  Ú!save_env_value.<locals>.<genexpr>ò
  s"   øé € ÐZÑ%5™'˜!Ô9NÈtÐUX×9Y—A’AÓ%5ùs   ƒ(ž
(ro  r  r#  )ri  r¶   r<  rE  rÒ  rŸ  r  r¨  r   rM  r$  rØ  rt  r  r  r]  r  )r¥   r  r  r$  Úserialized_valueÚidxs   f&    r8   r@  r@  ã
  s%  ø€ ô ˜#˜u×%Ò%ÙÜ# CÔ(Ø�M‰M˜$ Ó#×+Ñ+¨D°"Ó5€EÜ'¨¨UÓ3€EÜÔÜ‹~€Hä	˜×	"Õ	"Ø-5¯_©_×->Ò->” Ô)ÀBˆÜ+¨EÓ2ÐäÔZ¤Y¨uÔ%5ÓZÐ\`ÓaˆØŠ?Ø˜5 Ð"2Ð!3°2Ð6ˆEŠJç˜U 2�Y×/Ñ/°×5Ò5Ø�b—	˜TÕ!“	Ø�L‰L˜C˜5 Ð"2Ð!3°2Ð6Ô7ä˜¸¿¹Ó8IÕJ÷ 
#ô �s˜EÔ"ÜÖ÷ 
#×	"ús   Á6A$E ÃA%E Å E0	c                ó0   € V ^8„  d   QhR\         R\         /# )r3   Úidentityr4   rI   )r7   s   "r8   r9   r9   ÿ
  s   € ÷ Pñ P¤cð P¬cñ Pr:   c                ó²   € \         P                  ! RR\        T ;'       g    R4      P                  4       4      P	                  R4      pV'       d   RV R2# R# )aD  Env var name holding a custom endpoint's API key.
``identity`` is the endpoint's own id (Desktop endpoint id, or ``host:port`` for CLI setup),
so two endpoints on one host get separate slots. The fixed ``HERMES_CUSTOM_`` prefix keeps the
name POSIX-valid when the slug starts with a digit (``save_env_value`` rejects those).z
[^A-Z0-9]+r~  rL   ÚHERMES_CUSTOM_rp  ÚHERMES_CUSTOM_API_KEY)r¾  rÑ  rD   r©   r-  )ry  Úslugs   & r8   Úcustom_endpoint_key_envr~  ÿ
  sL   € ô
 �6Š6�- ¤c¨(¯.¨.°bÓ&9×&?Ñ&?Ó&AÓB×HÑHÈÓM€Dß.2ˆ^˜D˜6 Ð*ÐOÐ8OÐOr:   c                ó0   € V ^8„  d   QhR\         R\        /# r  rC   )r7   s   "r8   r9   r9     s   € ÷ ñ œ#ð ¤$ñ r:   c           	     ó(  € \        V R4      '       d   R# \        P                  V 4      '       g   \        RV : 24      h\	        4       pVP                  4       '       g   \        V R4       R# \        V4      ;_uu_ 4        \        V4      pV Uu. uF  p\        W04      '       d   K  VNK  	  pp\        V4      \        V4      8  pV'       d   \        WRR7       RRR4       \        V R4       \        4        X# u upi   + '       g   i     L-; i)zRRemove a key from ~/.hermes/.env and os.environ; True if it was found and removed.ÚremoveFr®   NTr  )ri  r¯   r°   r±   rŸ  r¨  r]  r  r   rU  r  r  r  )r¥   r  r$  r}  Ú	new_linesÚfounds   &     r8   Úremove_env_valuer„    sÔ   € ä˜#˜x×(Ò(ÙÜ×!Ñ! #×&Ò&ÜÐ>¸s¹gÐFÓGÐGÜ‹~€HØ�?‰?×ÒÜ˜3 Ô%Ùä	˜×	"Õ	"Ü Ó)ˆÙ&+ÓT¡e˜dÔ3HÈ×3S—T�T¡eˆ	ÐTÜ�I“¤ U£Ñ+ˆßÜ˜XÀÕE÷ 
#ô �s˜DÔ!ÜÔØ€Lùò U÷ 
#×	"ús$   Â DÂC<Â(C<Â..DÃ<DÄD	Útoken_firstc                ó<   € V ^8„  d   QhR\         R\         R\        /# )r3   ÚtokenrC  r…  rC   )r7   s   "r8   r9   r9     s"   € ÷ ñ ¤#ð ´ð ÔSWñ r:   c               ó‚   € T;'       g    \         pRV 3RV33pV'       d   TM
\        V4       F  w  rgV! Wg4       K  	  R# )zRWrite both Anthropic credential slots (one holds the value, the other is cleared).rº   r¹   N)r@  rW  )r‡  rC  Úsave_fnr…  ÚwriterÚorderr  r  s   &&&$    r8   Ú_write_anthropic_slotsrŒ    sD   € à×&Ð&œ€FØ Ð'Ð*=¸wÐ)GÐH€Eß +‘u´¸%³Ò@‰ˆÙˆtÖó Ar:   c                ó$   € V ^8„  d   QhR\         /# ©r3   r  rI   )r7   s   "r8   r9   r9   &  s   € ÷ /ñ /¤cñ /r:   c                ó    € \        V RV4       R# )zBPersist an Anthropic OAuth/setup token and clear the API-key slot.rL   N©rŒ  ©r  r‰  s   &&r8   Úsave_anthropic_oauth_tokenr’  &  s   € ä˜5 " gÖ.r:   c                ó    € \        RRV 4       R# )zHUse Claude Code's own credential files instead of persisting env tokens.rL   Nr�  )r‰  s   &r8   Ú%use_anthropic_claude_code_credentialsr”  +  s   € ä˜2˜r 7Ö+r:   c                ó$   € V ^8„  d   QhR\         /# rŽ  rI   )r7   s   "r8   r9   r9   0  s   € ÷ Bñ B¤#ñ Br:   c                ó"   € \        RWRR7       R# )zBPersist an Anthropic API key and clear the OAuth/setup-token slot.rL   F)r…  Nr�  r‘  s   &&r8   Úsave_anthropic_api_keyr—  0  s   € ä˜2˜u¸5×Ar:   c                ó^   € V ^8„  d   QhR\         R\         R\        \         \        3,          /# r†  )rD   rj  r   )r7   s   "r8   r9   r9   5  s.   € ÷ 	Cñ 	Cœsð 	C¬3ð 	C´4¼¼S¸µ>ñ 	Cr:   c                ó.   € ^ RI Hp V! W4       RRRV RR/# )zŒSave via the unified credential lifecycle (also refreshes any config.yaml mirror of the old
value and lifts a prior env-source suppression).©Úsave_provider_env_credentialÚsuccessTÚ	stored_asÚ	validatedF)Úhermes_cli.credential_lifecycler›  )r¥   r  r›  s   && r8   Úsave_env_value_securer   5  s%   € õ Mñ
 ! Ô,Ø�t˜[¨#¨{¸EÐBÐBr:   c                ó$   € V ^8„  d   QhR\         /# r2   r
  )r7   s   "r8   r9   r9   A  s   € ÷ ñ ”Cñ r:   c                 ó˜  € \        4       p ^ pV P                  4        FG  w  r#\        P                  P	                  V4      V8w  g   K+  V\        P                  V&   V^,          pKI  	  \        \        4      \        ,          \        V 4      ,
           F4  pV\        P                  9   g   K  \        P                  V V^,          pK6  	  V# )zÊRe-read ~/.hermes/.env into os.environ; returns count of vars changed.
Removes deleted vars only when known to Hermes (OPTIONAL_ENV_VARS and _EXTRA_ENV_KEYS) so
unrelated environment is never clobbered.)r.  r  rv  rw  rR  rà  rÓ  Ú_EXTRA_ENV_KEYS)Úenv_varsÚcountr¥   r  s       r8   Ú
reload_envr¦  A  s™   € ô ‹z€HØ€EØ—n‘nÖ&‰
ˆÜ�:‰:�>‰>˜#Ó %Ö'Ø#ŒB�J‰J�s‰OØ�Q�JŠEñ 'ô Ô%Ó&¬Õ8¼CÀ»M×IÐIˆØ”"—*‘*ÖÜ—
‘
˜3�Ø�Q�JŠEñ Jð €Lr:   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# r  rµ  )r7   s   "r8   r9   r9   R  s   € ÷ 	ñ 	œSð 	¤X¬c¥]ñ 	r:   c                ó€   €  ^ RI Hp T! T 4      #   \         d#    \        P                  P                  T 4      u # i ; i)ab  Read ``key`` from ``os.environ`` through ``agent.secret_scope.get_secret`` so an active
profile scope (multiplexed gateway turn) never leaks another profile's raw value. Falls back to
a plain environ read when the scope module is unavailable; ``UnscopedSecretError`` and scope
failures propagate -- a failed scoped read must never borrow the ambient env.)r¸  )r¹  r¸  rK  rv  rw  rR  )r¥   rº  s   & r8   Ú_scoped_environ_getr©  R  s;   € ð
#Ý@ñ �sÓÐøô ô #Ü�z‰z�~‰~˜cÓ"Ò"ð#ús   ‚ �*=¼=c                óF   € V ^8„  d   QhR\         R\        \         ,          /# r  rµ  )r7   s   "r8   r9   r9   ^  s   € ÷ 7ñ 7”sð 7œx¬�}ñ 7r:   c                óV   € \        V 4      pVf   \        4       P                  V 4      # T# )u¯  Get a value from ``os.environ`` (scope-aware) or ``~/.hermes/.env``.

The ``os.environ`` read routes through ``agent.secret_scope.get_secret`` so that, under an active
profile scope (multiplexed gateway turn), this is scope-checked rather than leaking another profile's
raw ``os.environ`` value. ``get_secret`` encodes the whole policy: global vars pass through; scope is
authoritative under multiplexing (miss -> None, no environ fallthrough); when multiplexing is off it
behaves exactly like the legacy ``os.environ`` read. Its siblings ``get_env_value_prefer_dotenv`` and
``gateway.config._getenv`` already work this way â€” this was the last scope-blind reader of the trio
(#67027).
)r©  r.  rR  )r¥   r1  s   & r8   r	  r	  ^  s(   € ô ˜cÓ
"€CØ"%¢+Œ8‹:�>‰>˜#ÓÐ6°3Ð6r:   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# r  rµ  )r7   s   "r8   r9   r9   m  s   € ÷ +ñ +¤Sð +¬X´c­]ñ +r:   c                óø   € \        4       P                  V 4      ;'       g    Rp\        V4      P                  4       P	                  R4      '       d   \        V 4      pV'       d   V# T;'       g    \        V 4      # )uË  Resolve a Hermes-managed credential preferring ``~/.hermes/.env`` over ``os.environ``, so a
deliberate .env edit beats a stale value inherited from the parent shell.

An unresolved ``op://`` reference left in .env yields to the already-resolved value from the
active secret scope (set by the 1Password secret source) â€” otherwise a provider auth attempt
would receive a URL instead of a key. Same carve-out as
``agent.credential_pool.get_env_prefer_dotenv``.rL   zop://)r.  rR  rD   rQ  r³   r©  )r¥   rž  Úscopeds   &  r8   Úget_env_value_prefer_dotenvr¯  m  s^   € ô ‹*�.‰.˜Ó
×
#Ð
# €CÜ
ˆ3ƒx‡�Ó×#Ñ# G×,Ò,Ü$ SÓ)ˆßØˆMØ×*Ð*Ô% cÓ*Ð*r:   c                ó0   € V ^8„  d   QhR\         R\         /# r  rI   )r7   s   "r8   r9   r9     s   € ÷ Bñ B”Cð BœCñ Br:   c                óR   € ^ RI Hp V! V \        R\        P                  4      R7      # )zRedact an API key for display.©Úmask_secretz	(not set))Úempty)Úagent.redactr³  r   r   ÚDIM)r¥   r³  s   & r8   Ú
redact_keyr·    s   € å(Ù�s¤%¨´V·Z±ZÓ"@ÔAÐAr:   z^\$\{[A-Za-z_][A-Za-z0-9_]*\}$c                ó0   € V ^8„  d   QhR\         R\        /# r  rC   )r7   s   "r8   r9   r9   •  s   € ÷ Uñ Uœsð U¤tñ Ur:   c                ó  € V P                  R^4      R,          P                  4       P                  RR4      p\        V 4      '       d   VP	                  \
        4      '       * # V\        9   ;'       g    VP	                  \        4      # )z¡Whether the LAST segment of a config key names a credential value. Header names
(``mcp_servers.<s>.headers.X-API-Key``) are folded to snake_case before matching.r�  r6  r~  r#  )Úrsplitr.  r<  rv  rt  Ú_NON_SECRET_KEY_SUFFIXESÚ_SECRET_CONFIG_KEYSÚ_SECRET_CONFIG_KEY_SUFFIXES)r¥   r±  s   & r8   Ú_is_secret_config_keyr¾  •  sk   € ð �:‰:�c˜1Ó˜bÕ!×'Ñ'Ó)×1Ñ1°#°sÓ;€DÜ˜#×ÒØ—=‘=Ô!9Ó:Ô:Ð:ØÔ&Ñ&×TÐT¨$¯-©-Ô8SÓ*TÐTr:   c                ó<   € V ^8„  d   QhR\         R\        R\         /# )r3   r  Ú_depthr4   r  )r7   s   "r8   r9   r9   ž  s!   € ÷ ñ œsð ¬Cð ¼ñ r:   c           
     ó  € ^ RI Hp V^8”  d   V # \        V \        4      '       dž   V P	                  4        UUu/ uF€  w  r4T\        V\
        4      '       dS   \        V4      '       dB   \        V\
        4      '       d,   V'       d$   \        P                  V4      '       g	   V! V4      M\        WA^,           4      bK‚  	  upp# \        V \        4      '       d#   V  Uu. uF  p\        WA^,           4      NK  	  up# V # u uppi u upi )z²Copy of ``value`` with credential-shaped keys masked. ``print`` bypasses the logging
redactor and opaque tokens miss the vendor-prefix regexes, so structural masking is required.r²  )rµ  r³  rŽ  rj  r  rD   r¾  Ú_ENV_PLACEHOLDER_REr°   Úredact_config_valuer  )r  rÀ  r³  r,  r¦  s   &&   r8   rÃ  rÃ  ž  sá   € õ )à�„{ØˆÜ�%œ×Òð Ÿ™œô'ñ
 &‘�ð	 Ü˜!œS×!Ò!Ô&;¸A×&>Ò&>Ä:ÈaÔQT×CUÒCU×Z[Ü'×-Ñ-¨a×0Ò0ñ ˜1Œ~ô % Q°­
Ó3ò4ñ &ò'ð 	'ô �%œ×ÒÙ<AÓB¹E°qÔ# A°¥zÖ2¹EÑBÐBØ€Lùó'ùò Cs   ¹AC=ÂC=Â!C=ÃDc                 ó:  € \        4       '       d   \        R4       R# \        4       p V P                  4       '       g   \	        V 4       \        RV  24       \        P                  R8X  d   . ROM. ROp\        P                  ! R4      ;'       g2    \        P                  ! R4      ;'       g    \        R V 4       R4      pV'       g   \        R4       \        R	V  24       R# \        R
V  RV R24       \        P                  ! V\        V 4      .RR7       R# )z"Open config file in user's editor.zedit configurationNzCreated Úwin32rx   ry   c              3   ób   "  € T F%  p\         P                  ! V4      '       g   K!  Vx € K'  	  R # 5ir+  )r±  Úwhich)r  Úcmds   & r8   r!  Úedit_config.<locals>.<genexpr>À  s   é € Ð8™
�¤f§l¢l°3×&7�Š›
ùs   ‚/¥
/z#No editor found. Config file is at:r!  zOpening r3  z...F)Úcheck)ÚnotepadÚcodeÚvimÚviÚnano)rÏ  rÍ  rÎ  rÌ  rË  )r  rh  r…  r¨  rµ  re  rf  Úplatformrv  Úgetenvr$  Ú
subprocessÚrunrD   )r”  Ú
candidatesÚeditors      r8   Úedit_configrÖ  ±  sí   € ä‡|‚|ÜÐ*Ô+ÙÜ!Ó#€KØ×Ñ×ÒÜ˜Ô%Ü�˜˜Ð&Ô'ô ?B¿l¹lÈgÔ>UÓ:Ú?ð ä�YŠY�xÓ ÷ @ð @¤B§I¢I¨hÓ$7÷ @ð @¼4Ù8™
Ó8¸$ó<@€FçÜÐ3Ô4Ü��;�-Ð Ô!Ùä	ˆH�[�M  f X¨SÐ
1Ô2Ü‡N‚N�FœC Ó,Ð-°U×;r:   c                ó$   € V ^8„  d   QhR\         /# r0  rI   )r7   s   "r8   r9   r9   Ê  s   € ÷ 4ñ 4¤sñ 4r:   c                ój   € \        \        .\        V 4      O5!  p\        V\        4      '       d   R# T# )z^Return the leaf value declared for *dotted_key* in ``DEFAULT_CONFIG`` (None for dicts/misses).N)r�  r´  r  rŽ  rj  )r1  rÿ  s   & r8   Ú_default_value_for_keyrÙ  Ê  s-   € ä”>Ð@¤O°JÓ$?Ó@€DÜ˜d¤D×)Ò)ˆ4Ð3¨tÐ3r:   Ú	providersc                ó:   € V ^8„  d   QhR\         \        ,          /# r2   )rà  rD   )r7   s   "r8   r9   r9   ñ  s   € ÷ Vñ Vœs¤3�xñ Vr:   c                 óL   € \        \        4      \        ,          \        ,          # )aN  Return the union of known top-level config keys for validation.

``_EXTRA_KNOWN_ROOT_KEYS`` are roots the runtime reads but DEFAULT_CONFIG deliberately
omits (``platform_toolsets``, ``smart_model_routing``, ...); without them every path under
such a root was flagged "not a recognized config key" with a difflib near-miss suggestion.
)rà  r´  Ú_EXTRA_KNOWN_ROOT_KEYSÚ_OPEN_SUBKEY_TOP_LEVEL_KEYSr=   r:   r8   Ú_known_top_level_keysrß  ñ  s   € ô Œ~ÓÔ!7Õ7Ô:UÕUÐUr:   c          	      ót   € V ^8„  d   QhR\         R\        \         ,          R\        R\        \         ,          /# )r3   r¥   rÔ  Úcutoffr4   )rD   rà  r   r   )r7   s   "r8   r9   r9   û  s9   € ÷ dñ dœcð d¬s´3­xð dÄð dÔQYÔZ]ÕQ^ñ dr:   c                ón   € \        \        \        P                  ! V \	        V4      ^VR7      4      R4      # )z9Closest candidate key name for a typo'd ``key``, or None.)r   rá  N)r$  ÚiterÚdifflibÚget_close_matchesrã  )r¥   rÔ  rá  s   &&&r8   Ú_suggest_closest_keyræ  û  s,   € ä””W×.Ò.¨s´F¸:Ó4FÈ!ÐTZÔ[Ó\Ð^bÓcÐcr:   c                óh   € V ^8„  d   QhR\         R\        \        \        \         ,          3,          /# r  )rD   r  r6   r   )r7   s   "r8   r9   r9      s(   € ÷ ?ñ ?œcð ?¤e¬D´(¼3µ-Ð,?Õ&@ñ ?r:   c                ó¦  € V '       g   R# \        V 4      pV^ ,          p^ RIHp VP                  R4      '       g   V\        9   g   W9   d   R# \        4       pW$9  d>   \        W$4      pVf   R# RP                  VR,          4      pRV'       d	   V RV 23# T3# V\        9   d   R# \        P                  ! V4      pV.pVR,           EF  p	V	\        9   g   \        V\        4      '       d	   V'       g   Ru # W—9  d²   RP                  V\        V4      R 4      p\        V4      ^ ,          \        \        4      \        ,          9   d   \        V4      ^ ,          '       d   RV3u # \        V	\        VP!                  4       4      4      p
V
e   RRP                  WŠ.,           4      3u # Ru # VP#                  V	4       Wy,          pEK  	  R# )	aà  Validate a dotted config-key path against the known schema -> ``(is_known, suggestion)``.

Headline case from #34067: ``gateway.discord.gateway_restart_notification`` was silently written, even
though ``gateway`` only has 4 known sub-keys (``strict``, ``media_delivery_allow_dirs``,
``trust_recent_files``, ``trust_recent_files_seconds``). The correct path is
``discord.gateway_restart_notification`` (platform configs live at the top level, not under a
``platforms`` namespace).
FN©ÚLEFT_CORE_TERMINAL_KEYSr~  r�  ºr  NN)FN)TN)r  Úhermes_cli.left_core_migrationrê  r³   Ú_PLATFORM_CONTAINER_KEYSrß  ræ  r  rÞ  r´  rR  rŽ  rj  r  rà  Ú_validate_config_keyrá  r  )r¥   ÚsegmentsÚtoprê  ÚknownÚ
suggestionÚrestrÿ  r8  ÚsegÚsiblings   &          r8   rî  rî     s¢  € ÷ ØÐä˜sÓ#€HØ
�1�+€Cõ GØ
‡~�~�c×Ò˜cÔ%=Ô=ÀÔA_ØÐä!Ó#€EØ
ÔÜ)¨#Ó5ˆ
ØÒØÐØ�x‰x˜ �Ó%ˆØ·˜˜ A d VÐ,ÐDÐD¸*ÐDÐDà
Ô)Ô)ØÐô ×"Ò" 3Ó'€DØˆu€HØ˜�|‰|ˆØÔ*Ô*´*¸TÄ4×2HÒ2H×PTØÒØŒ?ð —8‘8˜H¤S¨£] ^Ð4Ó5ˆDä Ó% aÕ(¬C´Ó,?ÔB]Õ,]Ô]Ü(¨Ó.¨q×1Ô1à˜d�{Ò"Ü*¨3´°D·I±I³KÓ0@ÓAˆGØÒ"Ø˜cŸh™h x°)Õ';Ó<Ð<Ò<ØÒØ�‰˜ÔØ�y‹ñ/ ð0 Ðr:   c                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# )r3   r¥   rò  r4   r¦   )r7   s   "r8   r9   r9   B  s%   € ÷ ñ ¤Sð ´h¼sµmð Ìñ r:   c                óØ   € V'       g   R# \        V 4      p\        V4      p\        V4      \        V4      8  ;'       d-    V\        V4      ) R V8H  ;'       d    \        V4      ^ ,          # )aˆ  Whether *suggestion* proves that *key* has only an extra prefix.

``DEFAULT_CONFIG`` is not a complete registry of runtime-read settings, so a
sibling spelling suggestion alone cannot prove an unseeded path is a typo.
A known suffix, such as ``gateway.discord.gateway_restart_notification``
-> ``discord.gateway_restart_notification``, is the narrow case where the
pre-write refusal is safe.
FN)r  r  rî  )r¥   rò  Úkey_segmentsÚsuggestion_segmentss   &&  r8   Ú_is_wrong_prefix_suggestionrú  B  sr   € ÷ ÙÜ" 3Ó'€LÜ)¨*Ó5ÐäÐÓ ¤3 |Ó#4Ñ4÷ 	0ð 	0Øœ#Ð1Ó2Ð2Ð3Ð4Ð8KÑK÷	0ð 	0ä  Ó,¨QÕ/ðr:   c                ó0   € V ^8„  d   QhR\         R\        /# r�  rC   )r7   s   "r8   r9   r9   V  s   € ÷ ñ ¤3ð ¬4ñ r:   c                óØ  € V P                  4       pVR,          R9   d   R# RV 9  d   R# V P                  4        F¬  pVP                  4       pVR8X  g   VP                  R4      '       d    R# VP	                  R4      w  rEpV'       d*   V'       d"   RV9  d   VP                  R	4      '       g    R# VP                  R
4      '       g   K’  RVRR 9  g   Kž  VRR '       g   K«   R# 	  R# )z©True when *value* plausibly encodes a YAML/JSON list or mapping. Deliberately conservative:
a bare leading ``-`` is not a trigger (``-5``, ``--flag`` must stay strings).:Nr  NTr"  Fr6  z- r[  r5  rp  rÂ  N)rÖ  Ú{r#  )rQ  Ú
splitlinesr-  r³   ry  rt  )r  r¯  r}  rŒ  ÚheadÚsepÚ_rests   &      r8   r  r  V  s¼   € ð �|‰|‹~€HØ�…|�zÔ!ÙØ�5ÔÙØ× Ñ Ö"ˆØ�z‰z‹|ˆØ�3Œ;˜$Ÿ/™/¨$×/Ò/ÚàŸ>™>¨$Ó/Ñˆ�5ß—4˜C tœO°D·O±OÀC×4HÒ4HÚØ�=‰=˜×Ô #¨T°#°2¨YÖ"6¸4ÀÀ¿9¹9Úñ #ñ r:   c                ó$   € V ^8„  d   QhR\         /# rŽ  rI   )r7   s   "r8   r9   r9   k  s   € ÷ ñ ”sñ r:   c                óJ   €  \        V 4      #   \        \        3 d     R# i ; i)zTint(value) for a clean integer literal (signs/whitespace/underscores OK), else None.N)r  r�  r±   rƒ  s   &r8   Ú_coerce_intr  k  s(   € ðÜ�5‹zÐøÜ”zÐ"ô Úðús   ‚
 �"¡"c                ó$   € V ^8„  d   QhR\         /# rŽ  rI   )r7   s   "r8   r9   r9   s  s   € ÷ 	ñ 	œñ 	r:   c                óä   €  \        V 4      pW8w  g>   V\        R4      \        R4      39   g#   \        V 4      \        \        V4      4      8w  d   R#  V#   \        \        \
        3 d     R# i ; i)z¨``float(value)`` only when the conversion preserves its decimal value; NaN/inf rejected.
Decimal-looking identifiers more precise than a binary float must stay strings.Úinfz-infN)r   r   rD   r�  r±   r   )r  r|  s   & r8   Ú_coerce_floatr  s  sk   € ðÜ�%‹LˆØŒ6�Qœ5 ›<¬¨v«Ð7Ô7¼7À5»>ÌWÔUXÐYZÓU[Ë_Ô;\Ùð <]ð €Høô ”zÔ#3Ð4ô Úðús   ‚AA ÁA/Á.A/r{  rE  Úonr|  ÚnoÚoffr–  c                ó<   € V ^8„  d   QhR\         R\         R\        /# r†  ©rD   r   )r7   s   "r8   r9   r9   ‡  s!   € ÷ "ñ "¤#ð "¬cð "´cñ "r:   c                ó�  € \        \        V 4      \        4      '       d   V R8X  d   \        V4      '       g   V# VP	                  4       pVP                  4       pV\        9   d   \        V,          # \        \        3 F  pV! V4      pVf   K  Vu # 	  \        V4      '       g   V#  \        P                  ! V4      p\        X\        \         34      '       d   V# V#   \        P                   dR   p\        \        TRR4      ;'       g    T4      P                  4       ^ ,          p\        RT  RT R24        Rp?L�Rp?ii ; i)a  Auto-coerce a ``hermes config set`` string to bool/None/int/float/list/dict.
String-typed settings (per ``DEFAULT_CONFIG``) are preserved verbatim so enum members such as
``approvals.mode="off"`` never become booleans. List/mapping literals are parsed so
isinstance-gated readers see real structures; the trigger is conservative.
Bare ``model`` is the exception: its string default is the model-id shorthand, so a structured
literal there is parsed for the section guard to gate instead of riding into model.default
as a bogus id (#131435).r  NÚproblemu   âœ— Value for 'z8' looks like a list/mapping but is not valid YAML/JSON (uc   ) â€” nothing was written.
  Fix the literal, or quote it (e.g. "'[text'") to store a plain string.)rŽ  rÙ  rD   r  r-  r.  Ú_SCALAR_WORDSr  r  r�  r  r  Úgetattrrþ  Ú_exit_invalidr  rj  )	r¥   r  r¯  r.  ÚcoerceÚcoercedr  r—  Údetails	   &&       r8   Ú_coerce_config_set_valuer  ‡  s.  € ô Ô(¨Ó-¬s×3Ò3Ø�7ŒNÔ6°u×=Ò=ØˆØ�{‰{‹}€HØ�N‰NÓ€EØ”ÔÜ˜UÕ#Ð#Ü¤Ó.ˆÙ˜Ó"ˆØÔØŠNñ /ô # 5×)Ò)Øˆð	ZÜ—’ Ó&ˆô �&œ4¤˜,×'Ò'Øˆà€Løô �>‰>ô Zô ”W˜S )¨TÓ2×9Ð9°cÓ:×EÑEÓGÈÕJˆÜØ˜c˜Uð #Øˆxð YðY÷	Zñ 	Zûð	Zús   Â)C ÃEÃ4AE Å Er  r  zmodel.aliasesÚmodel_aliaseszplugins.enabledzplugins.disabledz model_catalog.excluded_providerszagent.disabled_toolsetszskills.disabledc                ót   € V ^8„  d   QhR\         R\        \         \        3,          R\        \         ,          /# )r3   r¥   rÛ  r4   )rD   rj  r   r   )r7   s   "r8   r9   r9   ½  s.   € ÷ ñ ¤#ð ´D¼¼c¸µNð ÄxÔPSÅ}ñ r:   c                ób  € \        V 4      p\        \        .VO5!  p\        V4      ^8X  d   \	        V\
        4      '       d   Rp\        W4      pV\        P                  V 4      V3 FC  p\	        V\
        4      '       g   VR8X  d    R# \	        V\        4      '       g
   VR8X  g   KB   R# 	  R# )ax  ``"list"`` / ``"mapping"`` when the schema (``DEFAULT_CONFIG``, the known-container table,
or the value already on disk) fixes *key* to a container; ``None`` for scalars and open paths.
A single-segment key that is a mapping *section* in the schema skips the lookup: replacing a
whole section is ``_guard_section_overwrite``'s call (``--force``, the bare ``model`` shorthand).Nr  r  )
r  r�  r´  r  rŽ  rj  rT  r  rR  r  )r¥   rÛ  r  Úschema_noderÇ  rÿ  s   &&    r8   Ú_expected_container_typer  ½  s“   € ô
 ˜CÓ €EÜœ.Ð1¨5Ó1€KÜ
ˆ5ƒz�Q„œ: k´4×8Ò8ØˆÜ˜;Ó,€HØÔ4×8Ñ8¸Ó=¸xÓHˆÜ�dœD×!Ò! T¨YÔ%6ÚÜ�dœD×!Ò! T¨V¦^Úñ	 Iñ
 r:   c          
      óv   € V ^8„  d   QhR\         R\        R\        \         \        3,          R\        R\        /# )r3   r¥   r  rÛ  Úforcer4   )rD   r   rj  r6   )r7   s   "r8   r9   r9   Ï  s:   € ÷ +ñ +¬ð +´Sð +ÄtÌCÔQTÈHÅ~ð +Ô^bð +Ôgjñ +r:   c                ó¤  € \        W4      pVf   V# VR8X  d%   \        V\        4      '       d   V \        9   d   V.# VR8X  d   \        V\        4      M\        V\
        4      pV'       g   VR8X  d   V'       d   V# \        V\        4      '       g   \        V4      P                  MRpVR8X  d   RMRp\        RV  RV R	V R
V  RV R24       R# )u¥  Hard guardrail: never store a value of the wrong shape where the schema wants a list or a
mapping â€” every reader would ignore it while ``config get`` echoed it back. ``--force`` keeps
its documented meaning (replace a whole mapping section); a non-list in a list slot is never
readable, so it has no override. Returns the value to store: a bare name for a
``parse_config_string_list``-read slot becomes a one-item list.Nr  r  Ústringz[item, ...]z{key: value}u   âœ— Cannot set 'z': it must be a z, got a uR    â€” nothing was written.
  Pass a YAML/JSON literal, e.g.:
    hermes config set ú 'z!'
  or edit config.yaml directly.)	r  rŽ  rD   r  r  rj  r�  rP   r  )r¥   r  rÛ  r  ÚexpectedÚokÚgotÚliterals   &&&&    r8   Ú_refuse_container_type_mismatchr%  Ï  sÍ   € ô (¨Ó9€HØÒØˆØ�6Ôœj¨´×4Ò4¸Ô@]Ô9]ØˆwˆØ$,°Ô$6Œ�Eœ4Ô	 ¼JÀuÌdÓ<S€Bß	ˆh˜)Ô#¯ØˆÜ&0°¼×&<Ò&<Œ$ˆu‹+×
Ò
À(€CØ'¨6Ô1‰m°~€GÜØ
˜3˜%Ð/°¨z¸À#Àð GDØDGÀ5ÈÈ7È)ð T*ð	*ö+r:   c                óh   € V ^8„  d   QhR\         R\        \         \        \         ,          3,          /# r  )rD   r  r   )r7   s   "r8   r9   r9   å  s,   € ÷ Yñ Y¬ð Y´´c¼8ÄC½=Ð6HÕ0Iñ Yr:   c                óž  € \        V 4      pRp\        V4      ^8¼  dG   V^ ,          R8X  d9   V^,          R8X  d+   VR,          pRP                  V4      p RV^,           RV  R2p\        V4      ^8w  g   V^ ,          R8w  d   W3#  ^ R	IHp T^,          T9  d   Y3# R
T^,           RT^,           2pTRT R23#   \
         d    Y3u # i ; i)u.  Canonicalize ``platforms.<name>.<display_setting>`` -> ``display.platforms.<name>.<setting>``.
The gateway resolves per-platform display settings (streaming, show_reasoning, ...) from
``display.platforms``; the top-level ``platforms.<name>`` block holds only connection config.
Only known display settings (``OVERRIDEABLE_KEYS``) are redirected. Returns ``(key, note)``;
the gateway import is guarded so the CLI works where the gateway package is unavailable.

Before #71047 a write such as ``hermes config set platforms.telegram.streaming false`` landed on a key
the gateway never reads: ``config get`` echoed the new value back while the runtime kept the old
``display.platforms`` one â€” a silent no-op that looks like a duplicated key to the user.

``gateway.platforms.<name>.<field>`` is canonicalized to the top-level ``platforms.<name>.<field>``
first (#115212): ``merge_platform_sections`` reads both blocks but the top-level one wins on
shared keys, so a nested write beside an existing top-level value printed ``âœ“ Set`` while the
gateway kept the old value.
NÚgatewayr©  rë  r�  z!  (note: the top-level platforms.u/    block outranks gateway.platforms â€” saved as r™  )ÚOVERRIDEABLE_KEYSzdisplay.platforms.u3     (note: per-platform display setting â€” saved as )r  r  r  Úgateway.display_configr)  rK  )r¥   Úsegsrú  Ú_display_keysÚ	canonicals   &    r8   Ú_redirect_platform_display_keyr.  å  së   € ô  ˜3Ó€DØ€DÜ
ˆ4ƒy�A„~˜$˜q�' YÔ.°4¸µ7¸kÔ3IØ�B�xˆØ�h‰h�t‹nˆØ2°4¸µ7°)Ð;jÐknÐjoÐopÐqˆÜ
ˆ4ƒy�A„~˜˜a� KÔ/ØˆyÐðÝMð ˆA…w�mÔ#ØˆyÐØ$ T¨!¥W I¨Q¨t°A­w¨iÐ8€IØÐKÈIÈ;ÐVWÐXÐXÐXøô ô ØˆyÒðús   ÂB; Â;CÃCc                óF   € V ^8„  d   QhR\         R\        \         ,          /# )r3   Úrequested_keyr4   rµ  )r7   s   "r8   r9   r9     s   € ÷ ñ ´ð ¼Ä#½ñ r:   c                ó–   € \        V 4      p\        V4      ^8¼  d.   V^ ,          R8X  d    V^,          R8X  d   RP                  V4      # R# )aK  The ``gateway.platforms.<name>.<field>`` spelling the user typed, when that is what they typed.
``merge_platform_sections`` still honours a value that lives only there, so ``get`` must fall
back to it and ``unset``/``set`` must clear it, or the CLI reports "not set" / writes a value
while the gateway keeps reading the nested one.r(  r©  r�  N)r  r  r  )r0  r+  s   & r8   Ú_legacy_gateway_platforms_keyr2    s@   € ô
 ˜=Ó)€DÜ
ˆ4ƒy�A„~˜$˜q�' YÔ.°4¸µ7¸kÔ3IØ�x‰x˜‹~ÐÙr:   c                ó4   € V ^8„  d   QhR\         R\         RR/# rk  rI   )r7   s   "r8   r9   r9     s!   € ÷ ñ œcð ¬3ð °4ñ r:   c           
     óÊ   € \         P                  ! V 4      '       dG   \        RV RV  R\        R4       R2\        P
                  R7       \        P                  ! ^4       R# R# )zâA key pinned by the managed layer cannot be set/unset (the next load would reinstate it):
hard-reject and name the source. Distinct from ``is_managed()``; env-shaped keys route to the
.env writers, which carry their own guard.r^  r   z(': it is managed by your administrator (rƒ  zA) and cannot be changed. Contact your administrator to modify it.rc  N)r   Úis_key_managedre  rb  rf  rg  Úexitrc  s   &&r8   Ú_exit_if_key_managedr7    sa   € ô ×#Ò# C×(Ò(ÜØ�f�X˜R ˜uÐ$LÌ_Ð]jÓMkÐLlð mNð OÜUX×U_ÑU_õ	aô 	�Š�Žñ	 )r:   c                ó4   € V ^8„  d   QhR\         R\        RR/# rW  r  )r7   s   "r8   r9   r9     s!   € ÷ 	ñ 	œ#ð 	¤cð 	¨dñ 	r:   c                ó  € V R8X  di   \        V\        4      '       dQ   V'       dG    \        4       R,          V R2,          pVP                  4       '       d   VP	                  4        R# R# R# R# R#   \
         d     R# i ; i)z§``display.skin`` set means "apply NOW": bump the skin file's mtime so the gateway watcher's
(name, mtime) signature moves even when the name is unchanged. Best-effort.zdisplay.skinÚskinsz.yamlN)rŽ  rD   r!   r¨  ÚtouchrK  )r¥   r  Ú	skin_files   && r8   Ú_touch_skin_filer=    su   € ð ˆnÔ¤¨E´3×!7Ò!7¿Eð	Ü'Ó)¨GÕ3¸¸¸u°oÕEˆIØ×Ñ×!Ò!Ø—‘Ö!ñ "ñ =BÑ!7Ñøô
 ô 	Úð	ús   §AA2 Á2BÂ Bc                ó(   € V ^8„  d   QhR\         RR/# )r3   rq  r4   NrI   )r7   s   "r8   r9   r9   )  s   € ÷ ñ ”sð ˜tñ r:   c                 óh   € \        V \        P                  R 7       \        P                  ! ^4       R# )rc  N)re  rf  rg  r6  )rq  s   &r8   r  r  )  s   € Ü	ˆ#”C—J‘JÕÜ‡H‚HˆQ†Kr:   c                óV   € V ^8„  d   QhR\         R\        \        \        3,          RR/# )r3   r”  rÛ  r4   N)r	   rj  rD   r   )r7   s   "r8   r9   r9   .  s.   € ÷ Pñ P¤Dð P´t¼CÄ¸Hµ~ð PÈ$ñ Pr:   c                ó@   € \        4        ^ RIHp V! W\        4       R# )zBWrite only the user's raw config back (never the merged defaults).)Úrecording_raw_config_writeN)rÒ  r7  rB  rn  )r”  rÛ  rB  s   && r8   Ú_write_user_configrC  .  s   € äÔÝ[Ù˜{Ô9NÖOr:   c                óJ   € V ^8„  d   QhR\         R\        \         ,          RR/# )r3   r¥   rò  r4   Nrµ  )r7   s   "r8   r9   r9   5  s*   € ÷ Iñ I¤3ð I´H¼SµMð IÀdñ Ir:   c                 ór  € \        \        R V  R2\        P                  4      4       V'       d'   \        \        RV 2\        P                  4      4       \	        \        V 4      4      ^8X  d&   \        \        R\        P                  4      4       R# \        \        R\        P                  4      4       R# )õ   âš  'uU   ' is not a recognized config key â€” it was saved anyway, but Hermes may not read it.ú  Did you mean: z‚  (Custom top-level keys are supported and bridged to the environment for skills/external tools. Use --force to skip this notice.)z$  (Use --force to skip this notice.)N)re  r   r   ÚYELLOWr  r  r¶  )r¥   rò  s   &&r8   Ú_print_unknown_key_noticerI  5  sŽ   € Ü	Œ%Ø
�ˆuð &ð 	&Ü'-§}¡}ó6ô 7÷ ÜŒeÐ& z lÐ3´V·]±]ÓCÔDô Œ?˜3ÓÓ  AÔ%ÜŒeðä#ŸZ™Zó)ö 	*ô
 	ŒeÐ:¼F¿J¹JÓGÖHr:   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r3   r¥   r  r  rC   )r7   s   "r8   r9   r9   F  s&   € ÷ G3ñ G3œ#ð G3¤cð G3´$ñ G3r:   c                óº
  € \        4       '       d   \        R4       R# W P                  4       8w  g   V P                  4       '       g   \        RV : R24       R\	        V 4      9   d   \        RV : R24       \        V R4       \        V 4      '       d:   ^ RIHp  V! V P                  4       V4       \        R
V  R\        4        24       R# ^ RIHpHp V! V 4      '       d3    V! W4       \        R
V P                  4        R\        4        24       R# \!        V 4      p\#        V 4      w  rV'       d   \        V4       \%        V 4      w  ršV	'       g1   V'       g)   \'        W
4      '       d   ^ RIHp \        V! W
4      4       V R8X  d"   ^ RIHp V! V4      pV'       d   \        V4       \1        4       p\3        V4      p\5        W4      pVP7                  R4      pV P                  4       P9                  4       P;                  R4      '       d&   \=        V\>        4      '       d   V'       d   RV/VR&   ^ RI H!p V! WWò4      p \E        WWò4      p\=        V\F        4      '       d   VP7                  R4      MRp \I        WðV4       V'       d!   \K        W÷4      '       d   \        RV R24       Rp\?        T;'       g    R4      P                  4       ;'       g    RpV R8X  dè   VP9                  4       \?        V4      P                  4       P9                  4       8w  d®   ^ RI&H'p V! VP7                  R4      W4      w  ppV'       d@   RRPQ                  R VPS                  4        4       4      ,           RV RV RV R 2,           pMEV'       d>   \U        R!VR,          P7                  R"4       R#V R$V R%V R&2	\V        PX                  4      pV P                  4       P9                  4       R-9   d   \[        V4      pR'p \        R(4       \]        Wï4       \_        V 4      pV'       d   V R)8w  d   \a        V\c        V4      4       \e        W4       V R8X  d   ^ R*I3H4p V! 4        Tp\k        V 4      '       d-   \=        V\>        4      '       d   V'       d   ^ R+I6H7p V! V4      p\        R
V  R,V RV 24       V'       d   \        V4       V	'       g   V'       g   \q        W
4       R# R# R#   \         d   p\        R	T 24        Rp?ELTRp?ii ; i  \         d   p\        R	T 24        Rp?ELARp?ii ; i  \         d   p\        R	T 24        Rp?ELÍRp?ii ; i).u  Set a configuration value at a dotted ``key``; ``value`` is auto-coerced to bool/int/float.
``force`` writes a known key given under the wrong prefix (``gateway.discord.foo`` where
``discord.foo`` is known; otherwise refused â€” any other unknown path under a known section
is written with a did-you-mean notice), skips the unknown-top-level-key notice AND
authorizes replacing a mapping section with a scalar. Without it, scalar writes over mappings are refused and bare ``model`` is redirected
to ``model.default``.zset configuration valuesNu   âœ— Invalid config key: z# (empty or surrounding whitespace).rL   uH    â€” contains an empty path segment (leading, trailing, or doubled '.').rà  rš  õ   âœ— u   âœ“ Set r3  )Úis_env_setting_keyÚsave_env_setting)Úunknown_subkey_refusalzdisplay.language)Údisplay_language_errorr  úmodel.rŽ  )Ú_guard_section_overwriterý  z  (removed the shadowed z duplicate)zthe previous providerzmodel.provider)Údrop_stale_model_routez
  Cleared r^  c              3   ó8   "  € T F  w  rR V RV R2x € K  	  R# 5i)rQ  z (r™  Nr=   rÐ  s   &  r8   r!  Ú#set_config_value.<locals>.<genexpr>¤  s!   é € Ð(XÉÁÀ¨6°!°°B°q°c¸Õ);Ëùs   ‚u    â€” that route belonged to z, not z. z\'s endpoint resolves automatically; set model.base_url again if you meant a custom endpoint.u   âš  model.base_url (rH  z) was set under z and still applies to u%    â€” requests go there. If it is not zG's endpoint: `hermes config unset model.base_url` (and model.api_mode).zmodel.base_urlu<     (note: 'api_base' is an alias â€” saved as model.base_url)úterminal.cwd)Úreset_language_cacher²  rš  )zmodel.api_baser  )9r  rh  r-  r  r  r7  rv  rŸ  r›  r©   r±   re  rŸ  Úhermes_cli.config_env_routingrM  rN  r2  r.  rî  rú  Úhermes_cli.config_key_noticesrO  Úhermes_cli.config_languagerP  r…  rQ  r  rR  r.  r³   rŽ  rD   Úhermes_cli.config_section_guardrR  r%  rj  r;  rX  Úhermes_cli.route_identityrS  r  r  r   r   rH  r  rC  r’  r@  r„  r=  Ú
agent.i18nrW  r¾  rµ  r³  rI  )r¥   r  r  r›  r—  rM  rN  Ú
legacy_keyÚ_redirect_noteÚis_knownrò  rO  rP  Úlanguage_errorr”  rÛ  Ú
_model_valrR  Ú_old_providerr¤  Ú_route_noticerS  Ú_poppedÚ_unverifiedrŽ  rW  Ú_display_valuer³  s   &&&                         r8   Úset_config_valuerh  F  s£  € ô ‡|‚|ÜÐ0Ô1Ùà
�i‰i‹kÔ §¡§¢ÜÐ0°±Ð7ZÐ[Ô\Ø	Œ_˜SÓ!Ô!ÜØ& s¡gð .3ð 3ô	4ô ˜˜eÔ$Ü˜#×ÒÝPð	(Ù(¨¯©«°eÔ<ô 	�˜˜˜T¤,£.Ð!1Ð2Ô3ÙßRá˜#×Òð
	(Ù˜SÔ(ô 	�˜Ÿ™›˜ T¬,«.Ð)9Ð:Ô;Ùô /¨sÓ3€JÜ8¸Ó=Ñ€CßÜˆnÔÜ/°Ó4Ñ€H÷ ŸEÔ&AÀ#×&RÒ&RÝHÜÑ,¨SÓ=Ô>à
Ð Ô ÝEÙ/°Ó6ˆßÜ˜.Ô)ô "Ó#€KÜ6°{ÓC€KÜ$ SÓ0€Eð —‘ Ó)€JØ
‡y�yƒ{×ÑÓ×%Ñ% h×/Ò/´J¸zÌ3×4OÒ4O×T^Ø )¨:Ð6ˆ�GÑÝHÙ
" 3¨{Ó
B€CÜ+¨C¸ÓK€EÜ2<¸ZÌ×2NÒ2N�J—N‘N :Ô.ÐTX€Mð"Ü�K eÔ,÷ ”m K×<Ò<ÜÐ(¨¨°KÐ@ÔAð €MÜ˜×+Ð+¨Ó,×2Ñ2Ó4×OÐOÐ8O€MØ
ÐÔ =×#6Ñ#6Ó#8¼CÀ»J×<LÑ<LÓ<N×<TÑ<TÓ<VÔ#VÝDÙ5°k·o±oÀgÓ6NÐPUÓcÑˆ�ßà˜tŸy™yÑ(XÈÏÉÌÓ(XÓXÕXØ0°°¸vÀeÀWÈBÈuÈgð VZð ZõZñ ÷ Ü!Ø& {°7Õ';×'?Ñ'?À
Ó'KÐ&LÐL\Ð]jÐ\kð l$Ø$) 7Ð*OÐPUÈwð WMðMäNTÏmÉmó]ˆMð
 ‡y�yƒ{×ÑÓÐ<Ô<ô 1°Ó=ˆØˆÜÐLÔMÜ�{Ô0ô .¨cÓ2€Gß�3˜.Ô(Ü�wÔ 3°EÓ :Ô;ä�SÔ Ø
Ð Ô Ý3ÙÔð €NÜ˜S×!Ò!¤j°¼×&<Ò&<ÇÝ,Ù$ UÓ+ˆÜ	ˆH�S�E˜˜^Ð,¨D°°Ð
>Ô?ßÜˆmÔ÷ ŸEÜ! #Ö2ñ "‰8øô[ ô 	(Ü˜D  ˜,×'Ò'ûð	(ûô ô 	(Ü˜D  ˜,×'Ò'ûð	(ûôP ô "Ü˜˜Q˜C�j×!Ò!ûð"úsH   ÂS( Ã%T É<T6 Ó(TÓ3TÔTÔT3ÔT.Ô.T3Ô6UÕUÕUrx  c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r3   r¥   rx  rž  rC   )r7   s   "r8   r9   r9   Ð  s&   € ÷ 2^ñ 2^œ#ð 2^¬4ð 2^¼dñ 2^r:   c               ó   € ^ RI HpHp \        V 4      '       d'   \	        V P                  4       4      pVf   \        MTpMmV! V 4      '       d   V! V 4      pVf   \        MTpMJ\        V 4      p\        V 4      w  r\        4       p	\        W�4      pV\        J d   V'       d   \        W—4      pV\        J d   \        RV  24       ^ RIHp
Hp V'       gd   V
! 4       '       dW   \        V\         4      '       d6   \#        V 4      '       d$   \$        P'                  V4      '       g	   V! V4      pM\)        V4      p\+        \-        WaR7      RR7       \/        V 4      ^ ,          \1        4       9   d‘   \3        V 4      w  rÍV'       gz   \+        \5        RV  R	2\6        P8                  4      \:        P<                  R
7       V'       d9   \+        \5        RV 2\6        P8                  4      \:        P<                  R
7       R# R# R# R# )zôPrint a resolved configuration value. Credentials are masked unless ``--raw`` or
``security.redact_secrets: false``: ``print`` bypasses the log redactor, and the agent runs
this command from sessions whose transcripts persist (#84106, #110758).)rM  Úread_env_settingNúConfig key not set: )Ú_redact_enabledr³  )rx  T)r2  rF  uq   ' is not a recognized config key â€” Hermes may not read it; the value printed above comes from your config file.rc  rG  )rX  rM  rk  rv  r	  r©   rR  r2  r.  r–  rT  r  rµ  rm  r³  rŽ  rD   r¾  rÂ  r°   rÃ  re  r„  r  rß  rî  r   r   rH  rf  rg  )r¥   rx  rž  rM  rk  Ú	env_valuer  r^  r~  r5  rm  r³  r`  rò  s   &$$           r8   Úget_config_valuero  Ð  s“  € ÷ Sä˜#×ÒÜ! #§)¡)£+Ó.ˆ	Ø%Ò-•°9‰Ù	˜C×	 Ò	 Ù$ SÓ)ˆ	Ø%Ò-•°9‰ô 3°3Ó7ˆ
Ü/°Ó4‰ˆÜ“ˆÜ˜FÓ(ˆØ”HÓ§Ü Ó3ˆEà”ÓÜÐ,¨S¨EÐ2Ô3ç9ß‘?×$Ò$Ü�eœS×!Ò!Ü$ S×)Ò)Ô2E×2KÑ2KÈE×2RÒ2RÙ# EÓ*�øä'¨Ó.ˆEä	Ô
" 5Ô
:À$ÕGô �sÓ˜AÕÔ"7Ó"9Ô9Ü3°CÓ8ÑˆßÜ”%Ø˜�uð =ð =Ü>D¿m¹móMäSV×S]ÑS]õ_÷ Ü”eÐ.¨z¨lÐ;¼V¿]¹]ÓKÔRU×R\ÑR\×]ñ ñ	 ñ :r:   c                ó$   € V ^8„  d   QhR\         /# )r3   r¥   rI   )r7   s   "r8   r9   r9     s   € ÷ 61ñ 61œCñ 61r:   c                ó`  € \        4       '       d   \        R4       R# \        V R4       \        V 4      '       d^   ^ RIHp  V! V P                  4       4      P                  R4      pX'       g   \        RV  24       \        RV  R	\        4        24       R# ^ R
IHpHp V! V 4      '       d;    V! V 4      pX'       g   \        RV  24       \        RV  R	\        4        24       R# \        4       p\!        V4      p\#        V 4      p\%        V 4      w  r	V	'       d   \        V	P'                  RR4      4       \)        Wp4      p
V'       d   \)        Wx4      ;'       g    T
p
^ RIHp \/        V 4      ;'       g    VP                  V 4      pV'       d   V R8w  d   \1        V4      ;'       g    T
p
V
'       g   \        RV  24       \3        Wg4       \        RV  R	V 24       R#   \         d   p\        RT 24        Rp?ELšRp?ii ; i  \         d   p\        RT 24        Rp?ELqRp?ii ; i)z.Remove a user-set configuration or .env value.zunset configuration valuesNÚunset)Úremove_provider_env_credentialrƒ  rL  rl  u
   âœ“ Unset z from )rM  Úremove_env_settingzsaved aszresolved asré  rV  )r  rh  r7  rv  rŸ  rs  r©   rR  r±   r  re  rŸ  rX  rM  rt  r…  rQ  r2  r.  r<  rX  rì  rê  r’  r„  rC  )r¥   rs  rƒ  r—  rM  rt  r”  rÛ  r^  r_  Úremovedrê  rŽ  s   &            r8   Úunset_config_valuerv    sá  € ä‡|‚|ÜÐ2Ô3ÙÜ˜˜gÔ&ä˜#×Òõ 	Sð	(Ù2°3·9±9³;Ó?×CÑCÀGÓLˆE÷ ÜÐ0°°Ð6Ô7Ü�
˜3˜%˜v¤l£nÐ%5Ð6Ô7ÙßTá˜#×Òð	(Ù& sÓ+ˆE÷ ÜÐ0°°Ð6Ô7Ü�
˜3˜%˜v¤l£nÐ%5Ð6Ô7Ùä!Ó#€KÜ6°{ÓC€Kä.¨sÓ3€JÜ8¸Ó=Ñ€Cßäˆn×$Ñ$ Z°Ó?Ô@Ü˜KÓ-€GßÜ Ó8×CÐC¸GˆåFÜ-¨cÓ2×VÐVÐ6M×6QÑ6QÐRUÓ6V€Gß�3˜.Ô(Ü" 7Ó+×6Ð6¨wˆçÜÐ,¨S¨EÐ2Ô3ä�{Ô0Ü	ˆJ�s�e˜6 + Ð
/Ö0øôQ ô 	(Ü˜D  ˜,×'Ò'ûð	(ûô ô 	(Ü˜D  ˜,×'Ò'ûð	(ús0   Á%G" Â/H	 Ç"HÇ-HÈHÈ	H-ÈH(È(H-c                ó‚   € V ^8„  d   QhR\         R\        \         ,          R\        \        \         ,          ,          RR/# )r3   ÚusageÚexamplesÚextrar4   N)rD   r  r   )r7   s   "r8   r9   r9   @  s6   € ÷ ñ ”sð ¤d¬3¥ið ¼ÄÄcÅÕ8Kð ÐW[ñ r:   c                 óÜ   € \        V 4       \        4        \        R 4       V F  p\        RV 24       K  	  T;'       g    R F  p\        V4       K  	  \        P                  ! ^4       R# )z	Examples:r!  Nr=   )re  rf  r6  )rx  ry  rz  r}  s   &&& r8   Ú_usage_exitr|  @  sR   € Ü	ˆ%„LÜ	„GÜ	ˆ+ÔÛˆÜ��4�&ˆkÖñ à—�˜’ˆÜˆdŽñ ä‡H‚HˆQ†Kr:   c                ó   € V ^8„  d   QhRR/# r)  r=   )r7   s   "r8   r9   r9   K  s   € ÷ $ñ $ Tñ $r:   c                ób   €  V ! V!   R#   \          d   p\        RT 24        Rp?R# Rp?ii ; i)zvRun a config writer, surfacing the fail-closed write guard's RuntimeError as a clean CLI
error instead of a traceback.rL  N)ÚRuntimeErrorr  )ÚfnÚargsr—  s   &* r8   Ú_run_write_commandr‚  K  s/   € ð$Ù
ˆDŒ	øÜô $Ü˜˜S˜E�l×#Ò#ûð$ús   ‚
 Š.•)©.z/Usage: hermes config get <key> [--json] [--raw]z0Usage: hermes config set [--force] <key> <value>z Usage: hermes config unset <key>c                 ó¢   € \        V R R4      pV'       g   \        \          \        V\        V RR4      \	        \        V RR4      4      R7       R# )r¥   Nr  Frž  )rx  rž  )r  r|  Ú
_USAGE_GETro  r6   ©r�  r¥   s   & r8   Ú_cmd_config_getr†  a  sA   € Ü
�$˜˜tÓ
$€CßÜ”ZÑ Ü�S¤'¨$°¸Ó">ÄDÌÐQUÐW\Ð^cÓIdÓDe×fr:   c                 ó´   € \        V R R4      p\        V RR4      pV'       d   Vf   \        \          \        \        W\        \        V RR4      4      4       R# )r¥   Nr  r  F)r  r|  Ú
_USAGE_SETr‚  rh  r6   )r�  r¥   r  s   &  r8   Ú_cmd_config_setr‰  h  sI   € Ü
�$˜˜tÓ
$€CÜ�D˜' 4Ó(€Eß�%’-Ü”ZÑ ÜÔ'¨´T¼'À$ÈÐQVÓ:WÓ5XÖYr:   c                 óh   € \        V R R4      pV'       g   \        \          \        \        V4       R# r`  )r  r|  Ú_USAGE_UNSETr‚  rv  r…  s   & r8   Ú_cmd_config_unsetrŒ  p  s&   € Ü
�$˜˜tÓ
$€CßÜ”\Ñ"ÜÔ)¨3Ö/r:   c                ó^   € V ^8„  d   QhR\         \        \        3,          R\        R\        /# )r3   r{  Úfmtr4   r   )r7   s   "r8   r9   r9   w  s)   € ÷ =ñ =œœS¤#˜X�ð =¬Sð =´Sñ =r:   c                 óˆ   € V P                  R . 4      pV'       d(   VP                  RP                  VR,          4      4      # R# )Útoolsr^  :Nr3   NrL   )rR  r7   r  )r{  rŽ  r�  s   && r8   Ú_tools_suffixr‘  w  s5   € Ø�H‰H�W˜bÓ!€Eß/4ˆ3�:‰:�d—i‘i  b¥	Ó*Ó+Ð<¸"Ð<r:   c                ó(   € V ^8„  d   QhR\         RR/# )r3   Útextr4   NrI   )r7   s   "r8   r9   r9   |  s   € ÷ ñ œð  ñ r:   c                 ó’   € \        4        \        \        V \        P                  \        P                  4      4       \        4        R # r+  )re  r   r   ÚCYANÚBOLD)r“  s   &r8   Ú_print_bannerr—  |  s%   € Ü	„GÜ	Œ%�”f—k‘k¤6§;¡;Ó
/Ô0Ü	†Gr:   c           
      óª  € \        R 4       \        RR7      p\        4       p\        RR7      w  r4V'       g>   V'       g6   W48¼  d0   \	        \        R\        P                  4      4       \	        4        R# W48  d   \	        RV RV 24       V'       d   \	        R	\        V4       R
24       V Uu. uF  qUP                  R4      '       g   K  VNK  	  ppV Uu. uF6  qUP                  R4      '       d   K  VP                  R4      '       d   K4  VNK8  	  ppRVR3RVR33 Fi  w  r‰p
V	'       g   K  \	        R	VP                  \        V	4      4       24       V	 F-  p\	        RVR,           V
'       d   \        Wº4      MR 24       K/  	  Kk  	  \	        4        \        RRR7      p\	        4        VR,          '       g   VR,          '       d$   \	        \        R\        P                  4      4       VR,          '       dA   \	        4        VR,           F)  p\	        \        RV 2\        P                  4      4       K+  	  \	        4        R# u upi u upi )u*   ðŸ”„ Checking configuration for updates...FrZ  TrR  u    âœ“ Configuration is up to date!Nú  Config version: rY  r�  z1 new config option(s) will be added with defaultsr  Úadvancedu'   âš ï¸�  {} required API key(s) missing:rL   u.   â„¹ï¸�  {} optional API key(s) not configured:z (enables: {})u	        â€¢ r  )rL  rM  r>  rP  u   âœ“ Configuration updated!rQ  u
     âš ï¸�  )r—  r  r—  rô  re  r   r   ÚGREENr  rR  r7   r‘  rt  rH  )r�  rr  Úmissing_configrm  rl  r¦  Úrequired_missingÚoptional_missingr‰  rÃ  r»  rŸ  r;  r¼  s   &             r8   Ú_cmd_config_migraterŸ  ‚  sÝ  € ÜÐ>Ô?ä&°UÔ;€KÜ.Ó0€NÜ2ÈÔMÑ€KçŸ~°+Ô2KÜŒeÐ6¼¿¹ÓEÔFÜŒÙàÔÜÐ" ; -¨u°Z°LÐAÔBçÜ�”S˜Ó(Ð)Ð)ZÐ[Ô\á#.ÓG¡;˜a·%±%¸×2FŸ˜¡;ÐÐGÙ#.Óe¡;˜a·e±e¸M×6JœÐST×SXÑSXÐYc×SdŸ˜¡;ÐÐeà	2Ð4DÀbÐIØ	9Ð;KÐM]Ð^ó#`Ñˆ˜÷ ‰5Ü�D˜Ÿ™¬¨E«
Ó3Ð4Ð5Ô6Û�Ü˜	 # f¥+ ÏV¬}¸SÔ/IÐY[Ð.\Ð]Ö^ó ñ#`ô 
„GÜ¨°UÔ;€GÜ	„GØˆ{×Ô˜w ~×6Ô6ÜŒeÐ0´&·,±,Ó?Ô@Øˆz×ÔÜŒØ˜z×*Ð*ˆGÜ”%˜* W IÐ.´·±Ó>Ö?ñ +ä	†Gùò' HùÚes   Â0IÃIÃIÃ6IÄIc           	     óš  € \        R4       \        RR7      w  rW8¼  d   \        RV R24       M*\        \        RV RV R2\        P
                  4      4       R\        R	 3R
\        R 33pV Fw  w  rEp\        4        \        \        RV R2\        P                  4      4       VP                  4        F,  w  rx\        \        V4      '       d   RV 2MV! Wx4      4       K.  	  Ky  	  \        4       p	V	'       dF   \        4        \        \        R\        V	4       R2\        P
                  4      4       \        R4       ^ RIHp
 V
! \        4       \        4      pV'       d]   \        4        \        \        R\        P                  4      4       V F)  p\        \        RV 2\        P
                  4      4       K+  	  \        4        R# )z:Non-interactive report of missing and stale configuration.u   ðŸ“‹ Configuration StatusTrR  r™  u    âœ“rY  z (update available)ÚRequiredc                 ó>   € \        R V  R2\        P                  4      # )u       âœ— z
 (missing))r   r   ÚRED©r   r  s   &&r8   Ú<lambda>Ú#_cmd_config_check.<locals>.<lambda>µ  s   € ´U¸XÀaÀSÈ
Ð;SÔU[×U_ÑU_Ô5`r:   r   c                 óT   € \        R V  \        VR4       2\        P                  4      # )u       â—‹ u    â†’ {})r   r‘  r   r¶  r¤  s   &&r8   r¥  r¦  ·  s"   € ”e˜h q c¬-¸¸9Ó*EÐ)FÐGÌÏÉÔTr:   r!  rÂ  u       âœ“ z new config option(s) availablez+    Run 'hermes config migrate' to add them)Úconfig_check_diagnosticsz  Saved configuration:u       âš  N)r—  rô  re  r   r   rH  r  rÓ  r–  r  r	  r—  r  Ú#hermes_cli.config_check_diagnosticsr¨  rJ  )r�  rm  rl  r
  Útitler  Úmissing_liner  r{  rœ  r¨  ÚdiagnosticsÚ
diagnostics   &            r8   Ú_cmd_config_checkr®  ª  sx  € äÐ-Ô.ä2ÈÔMÑ€KØÔ ÜÐ" ; -¨tÐ4Õ5äŒeÐ(¨¨°U¸:¸,ÐFYÐZÔ\b×\iÑ\iÓjÔkð 
Ô&Ñ(`ÐaØ	Ô&Ù	Tð	VðW€Fó '-Ñ"ˆ�lÜŒÜŒe�b˜˜˜q�M¤6§;¡;Ó/Ô0Ø#Ÿk™kžm‰NˆHÜ¬=¸×+BÒ+B�H˜X˜JÑ'ÉÐU]ÓHdÖeó ,ñ '-ô /Ó0€NßÜŒÜŒe�bœ˜^Ó,Ð-Ð-LÐMÌvÏ}É}Ó]Ô^ÜÐ;Ô<åLá*Ô+CÓ+EÄ}ÓU€KßÜŒÜŒeÐ,¬f¯k©kÓ:Ô;Û%ˆJÜ”%˜( : ,Ð/´·±Ó?Ö@ñ &ô 
†Gr:   c                ó   € V ^8„  d   QhRR/# r)  r=   )r7   s   "r8   r9   r9   Ð  s   € ÷ ñ ˜$ñ r:   c                  ó    € ^ RI Hp  V ! 4        R# )r®  ©Úshow_configN)Úhermes_cli.config_showr²  r±  s    r8   Ú_cmd_config_showr´  Ð  s
   € Ý2Ù†Mr:   c                 ó   € \        4       # r+  ©r´  ©r�  s   &r8   r¥  r¥  Ö  s   € Ô'Ô)r:   Úshowc                 ó   € \        4       # r+  r¶  r·  s   &r8   r¥  r¥  ×  s   € Ô)Ô+r:   Úeditc                 ó   € \        4       # r+  )rÖ  r·  s   &r8   r¥  r¥  Ø  s   € œœr:   rR  rà  rr  r'  c                 ó(   € \        \        4       4      # r+  )re  r…  r·  s   &r8   r¥  r¥  Ü  s   € œœÓ0Ô1r:   zenv-pathc                 ó(   € \        \        4       4      # r+  )re  rŸ  r·  s   &r8   r¥  r¥  Ý  s   € œU¤<£>Ô2r:   ÚmigraterÊ  a
  Available commands:
  hermes config           Show current configuration
  hermes config edit      Open config in editor
  hermes config get <key>          Print a resolved config value
  hermes config set <key> <value>   Set a config value
  hermes config unset <key>        Remove a config value
  hermes config check     Check for missing, outdated, or inactive config
  hermes config migrate   Update config with new options
  hermes config path      Show config file path
  hermes config env-path  Show .env file pathc                óà   € \        V RR4      p\        P                  V4      pVe   V! V 4       R# \        RV 24       \        4        \        \        4       \
        P                  ! ^4       R# )zHandle config subcommands.Úconfig_commandNzUnknown config command: )r  Ú_CONFIG_SUBCOMMANDSrR  re  Ú_CONFIG_USAGErf  r6  )r�  ÚsubcmdÚhandlers   &  r8   rÀ  rÀ  í  sY   € ä�TÐ+¨TÓ2€FÜ!×%Ñ% fÓ-€GØÒÙ�ŒÙÜ	Ð$ V HÐ
-Ô.Ü	„GÜ	Œ-ÔÜ‡H‚HˆQ†Kr:   c                ó   € V ^8„  d   QhRR/# r)  r=   )r7   s   "r8   r9   r9   ü  s   € ÷ ñ  $ñ r:   c                 ó´  €  ^ RI Hp  V ! 4        F³  pVP                  R8w  d   K  VP                   F�  pV\        9   d   K  VP                  R4      '       * pVP                  ;'       g    VP                  pRT RV'       d   RMR 2RT RV'       d   RMR 2R	VP                  ;'       g    R
RVRRRR/\        V&   K�  	  Kµ  	  R
#   \         d     R
# i ; i)zxExpose env_vars of every ``auth_type="api_key"`` provider in providers/ via OPTIONAL_ENV_VARS
without editing this file.)Úlist_providersrC  r�  r5  zAPI keyzbase URL overrider:  z"base URL (leave empty for default)r\  Nr=  Úcategoryrý  rš  T)Ú	_BASE_URLÚ_URL)
rÚ  rÇ  Ú	auth_typer¤  rÓ  rt  Údisplay_namer  Ú
signup_urlrK  )rÇ  Ú_ppÚ_varÚ_is_keyÚ_labels        r8   Ú_inject_profile_env_varsrÒ  ü  sÖ   € ðÝ,Ù!Ö#ˆCØ�}‰} 	Ô)ÙØŸœ�ØÔ,Ô,ÙØ"Ÿm™mÐ,AÓBÔB�Ø×)Ñ)×5Ð5¨S¯X©X�à! f X¨Q¿G©yÐI\Ð.]Ð#^Ø  ¨·w©)ÐDhÐ)iÐjØ˜3Ÿ>™>×1Ð1¨TØ Ø 
Ø ð+&Ô! $Ó'ó %ó $øô ô Úðús*   ‚A'C Á*C ÂC ÂC Â-C ÃCÃCc                ó0   € V ^8„  d   QhR\         R\        /# r´  rC   )r7   s   "r8   r9   r9     s   € ÷ ?ñ ?œcð ?¤dñ ?r:   c                 ó`   € V P                  R 4      ;'       d    V P                  R 4      '       * # )Ú__)r³   rt  )r  s   &r8   Ú_is_plugin_dir_namerÖ    s'   € ð —‘ Ó%×=Ð=¨$¯-©-¸Ó*=Ô>Ð>r:   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r3   r·  Úsource)r   r	   ÚPlatformManifestSource)r7   s   "r8   r9   r9      s   € ÷ )ñ )¤8¬D¥>ð )ÔBXñ )r:   c           	   #  ó  "  € . pVR9   d*   VP                  \        4       R,          R,          R34       VR9   d-   V e   T M	\        4       R,          pW#R,          R3VR3.,          pV Fô  w  rE \        P                  ! V4      ;_uu_ 4       pV Uu. uF"  p\        VP                  4      '       g   K   VNK$  	  ppRRR4       X F“  p
 T
P                  4       '       g   K   R Fp  p\        T
P                  4      T,          p \        P                  ! T4      p\        P                   ! TP"                  4      '       g   K^  T
P                  YÅT3x €  K‘  	  K•  	  Kö  	  R# u upi   + '       g   i     L´; i  \        \        3 d     EK'  \         d   p	\        T4      RYY3x €  Rp	?	EKH  Rp	?	ii ; i  \         d     EK  i ; i  \         d   p	T
P                  RYY3x €  Rp	?	 EK*  Rp	?	i\         d     EK  i ; i5i)	a\  Yield ``(dir_name, manifest_path, require_kind, stat)`` for every platform plugin manifest.
``source`` is ``"bundled"`` (shipped ``plugins/platforms/*``), ``"user"`` (``<home>/plugins/
platforms/*`` plus flat ``<home>/plugins/*`` installs, which must declare ``kind: platform``,
#46600) or ``"all"``. ``home`` defaults to the bound Hermes home. A directory that cannot be
listed or searched yields ``(name, None, require_kind, error)``: a plugin there can't load
either, so callers skip it. One ``scandir`` per root and one ``stat`` per candidate, because
the child-env scrub stamps these on every spawn.Úpluginsr©  FNT)rÔ  Úbundled)rÔ  Úuser)zplugin.yamlz
plugin.yml)r  r:  r!   rv  ÚscandirrÖ  r  rz  ÚNotADirectoryErrorr/  rD   r@  r	   r'  r:  ÚPermissionErrorÚS_ISREGr0  )r·  rØ  ÚrootsÚuser_pluginsrA  Úrequire_kindÚitr¤  rÓ  r—  r¸  Ú	file_namer'  r°  s   &&            r8   Ú_platform_manifest_pathsrç     s¼  é € ð €EØÐ#Ô#Ø�‰Ô&Ó(¨9Õ4°{ÕBÀEÐJÔKØ�Ô Ø $Ò 0™´oÓ6GÈ9ÕTˆØ +Õ-¨uÐ5¸ÀdÐ7KÐLÕLˆÛ#Ñˆð	Ü—’˜D×!Ô! RÙ&(ÓH¡b Ô,?ÀÇÁ×,GŸ1˜1¡b�ÐH÷ "ó ˆEðØ—|‘|—~’~Ùð &ó ;�	Ü˜EŸJ™JÓ'¨)Õ3�ðÜŸš ›�Bô —|’| B§J¡J×/Ò/ÙØ—j‘j $°bÐ8Ò8Úó ;ó ó $ùò I÷ "×!ûä!Ô#5Ð6ô 	ÛÜô 	Ü�d“)˜T <Ð4Ò4Þûð	ûô ô Ûðûô 'ô ØŸ*™* d¨LÐ=Ò=ßûÜô Ûðüsä   ‚A-HÁ0E<ÂE)ÂE$
Â5E$
Â;E)Â=E<ÃHÃF:Ã!$HÄGÄ%HÅ"HÅ$E)Å)E9Å4E<Å8HÅ9E<Å<F7ÆHÆF7ÆF7ÆF2Æ+HÆ2F7Æ7HÆ:G
ÇHÇ	G
Ç
HÇH	ÇG1	Ç)HÇ1H	Ç>H	Ç?HÈH	ÈHc                óF   € V ^8„  d   QhR\         \        ,          R\        /# ©r3   r·  r4   )r   r	   r  )r7   s   "r8   r9   r9   L  s"   € ÷ Vñ V¤(¬4¥.ð V¼Eñ Vr:   c                ó‚   € \         ;QJ d    . R \        V R4       4       F  NK  	  5# ! R \        V R4       4       4      # )zðChange-detection key over every user platform plugin manifest of ``home`` (path plus
:func:`utils.file_signature`): it changes when one is added, removed, replaced or edited in
place, so a cache keyed on it never serves a stale declaration.c              3   óˆ   "  € T F8  w  rr4T\        V4      Ve   \        V4      M\        V4      P                  3x € K:  	  R # 5ir+  )rD   r%   r�  rP   )r  r  r'  Ú_kindr°  s   &    r8   r!  Ú*platform_manifest_stamp.<locals>.<genexpr>P  s?   é € ð VÙ.TÑ*�T ð œ˜D›	¸Ò9I¤>°"Ô#5ÌtÐTVËx×O`ÑO`ÕaÛ.Tùs   ‚A ArÝ  )r  rç  )r·  s   &r8   Úplatform_manifest_stamprî  L  sK   € ÷ Œ5ñ VÜ.FÀtÈVÔ.TóV�5ð Vˆ5ñ VÜ.FÀtÈVÔ.TóVó Vð Vr:   ÚstrictÚskippedc          	      ól   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R,          /# )r3   r·  rØ  rï  rð  N)r   r	   rÙ  r6   r  )r7   s   "r8   r9   r9   T  s3   € ÷ %!ñ %!¤X¬d¥^ð %!ÔDZð %!Ü'+ð%!Ü>BÀT½kñ%!r:   c             #  óà  "  € ^ RI Hp V! 4       '       d   R# \        W4       F§  w  rVrxVf.   \        P	                  RWX4       Ve   VP                  V4       K7   \        VRRR7      ;_uu_ 4       p	\        V	4      ;'       g    / p
RRR4       \        X
\        4      '       d   T'       d   T
P                  R4      R	8w  d   K¢  YZ3x € K©  	  R#   + '       g   i     LQ; i  \         dR   pT'       d
   T'       g   h \        P	                  RYk4       Te   TP                  \        T4      4        Rp?EK  Rp?i\         d$    Te   TP                  \        T4      4        EKG  i ; i5i)
aç  Yield ``(dir_name, manifest_dict)`` for every platform plugin manifest (see
:func:`_platform_manifest_paths`). ``strict`` raises when a manifest cannot be read instead of
skipping it: the child-env scrub must not lose a declared secret to an I/O error. Only a
manifest known to be a platform's counts (the bundled and ``plugins/platforms/`` dirs); a
flat ``plugins/*`` manifest proves it is one only by its content, so an unreadable one is
skipped with a warning, as is an unsearchable plugin directory. A manifest that does not
parse declares nothing (its adapter cannot load either) and is skipped. Every skip is appended
to ``skipped``, so a caller can tell a complete scan from a partial one. A safe worker reads
no plugin manifest at all.)Úsafe_worker_enabledNz+Skipping unreadable plugin directory %s: %srn  r)  r*  z*Skipping unreadable plugin manifest %s: %sr  rÐ  )r1  ró  rç  r’  r¼  r  rx  r$   r/  rD   rK  rŽ  rj  rR  )r·  rØ  rï  rð  ró  Údir_nameÚmanifest_pathrä  r°  r|  Úmanifestr—  s   &&$$        r8   Ú_platform_plugin_manifestsr÷  T  s  é € õ =á×ÒÙÜ5MÈdÖ5[Ñ1ˆ ØÒ Ü�N‰NÐHÈ(ÔWØÒ"Ø—‘˜xÔ(Ùð	Ü�m S°;×?Õ?À1Ü)¨!Ó,×2Ð2°�÷ @ô ˜(¤D×)Ò)¯l¸x¿|¹|ÈFÓ?SÐWaÔ?aÙØÐ Ô ó- 6\÷ @×?ûäô 	ßŸlØÜ�N‰NÐGÈÔ\ØÒ"Ø—‘œs =Ó1Ô2ÞûÜô 	ØÒ"Ø—‘œs =Ó1Ô2Ûð	üsr   ‚AE.ÁC#Á1CÂC#ÂE.Â-#E.ÃC ÃC#ÃE.Ã C#Ã#E+Ã.D:Ã>5D:Ä3E.Ä:E+ÅE+Å&E.Å*E+Å+E.Úoptionalc                ó0   € V ^8„  d   QhR\         R\        /# )r3   rö  rø  )rj  r6   )r7   s   "r8   r9   r9   €  s   € ÷ $ñ $¬Tð $Äñ $r:   c             #  ó\  "  € . V P                  R4      ;'       g    . OV'       d   V P                  R4      ;'       g    . M. O Fá  p\        V\        4      '       d   RV/M\        V\        4      '       d   TM/ pVP                  R4      pV'       d   \        V\        4      '       g   Kh  \	        VP                  R4      ;'       g    VP                  R4      4      pV'       g9   VP                  R4      RJ g$   VP                  4       P                  \        4      pWEV3x € Kã  	  R# 5i)a]  Yield ``(name, is_secret, meta)`` for a manifest's ``requires_env`` (and, unless
``optional=False``, ``optional_env``) entries (a bare name or a dict with ``name`` plus optional
``description``/``url``/``password``/``prompt``/``category``). A name ending in
PLATFORM_SECRET_ENV_SUFFIXES is a password field unless the entry says ``password: false``.Úrequires_envÚoptional_envr  r=  ÚsecretFN)rR  rŽ  rD   rj  r6   r©   rt  ÚPLATFORM_SECRET_ENV_SUFFIXES)rö  rø  r¸  Úmetar  Ú	is_secrets   &$    r8   Ú_platform_manifest_env_entriesr  €  sè   é € ð
 v�H—L‘L Ó0×6Ð6°BÐu×ck¸H¿L¹LÈÓ<X×<^Ð<^Ð\^øÐqsÓuˆÜ",¨U´C×"8Ò"8�˜‰ÄzÐRWÔY]×G^ÒG^¹eÐdfˆØ�x‰x˜Óˆßœ: d¬C×0Ò0ÙÜ˜Ÿ™ *Ó-×CÐC°·±¸(Ó1CÓDˆ	ß §¡¨*Ó!5¸Ó!>ØŸ
™
›×-Ñ-Ô.JÓKˆIØ˜tÐ#Ô#ó vùs#   ‚$D,§D,¿AD,Â4D,Ã
D,Ã(AD,c                ó:   € V ^8„  d   QhR\         \        ,          /# r2   ©Ú	frozensetrD   )r7   s   "r8   r9   r9   �  s   € ÷ Kñ K¬	´#­ñ Kr:   c                óX  € V  UUUUUu0 uFV  w  r\        V4       FB  w  r4pV'       g   K  VP                  R4      ;'       g    RR8X  g   K2  VP                  4       kKD  	  KX  	  pppppp\        T\         Uu0 uF  qwP                  4       kK  	  up,
          4      # u upppppi u upi )z¤Upper-cased secret messaging env names the given manifests declare, minus core-declared
names: a manifest never reclassifies a core variable such as OPENAI_API_KEY.rÈ  Ú	messaging)r  rR  r©   r  ÚCORE_DECLARED_ENV_NAMES)Ú	manifestsÚ_dirrö  r  r   rÿ  Únamesr   s   &       r8   Ú_manifest_secret_envsr  �  s—   € ñ 1:÷ T±	™n˜dÜ*HÈÖ*RÑ&� $Üô à#Ÿx™x¨
Ó3×BÐB°{À{ÑRô ˆT�Z‰ZŽ\Ù*Rñ ±	€Eô Tô �UÕ1HÓIÑ1H¨AŸg™gžiÑ1HÑIÕIÓJÐJùöTùò Js   ‰B«BÁBÁBÁ9B'
c          	      ót   € V ^8„  d   QhR\         \        ,          R\        R\        R\        \
        ,          /# )r3   r·  rØ  rï  r4   )r   r	   rÙ  r6   r  rD   )r7   s   "r8   r9   r9   ™  s9   € ÷ Zñ Z¬´­ð ZÔG]ð ZÜ*.ðZÜ;DÄS½>ñZr:   c               óX   € VR8X  d   \         e   \         # \        \        WVR7      4      # )a  Secret env names declared by one source's platform plugin manifests: ``"user"`` reads only
``home``'s user-installed plugins, which belong to that profile alone; ``"bundled"`` returns
the set read once at import (re-read strictly if that read hit an I/O error).rÜ  )rï  )ÚBUNDLED_PLATFORM_SECRET_ENVSr  r÷  )r·  rØ  rï  s   &&$r8   Úplatform_manifest_secret_envsr  ™  s,   € ð
 �ÔÔ;ÒGÜ+Ð+Ü Ô!;¸DÐQWÔ!XÓYÐYr:   c                ó~   € V ^8„  d   QhR\         \        ,          R\        \        \        ,          \
        3,          /# ré  )r   r	   r  r  rD   r6   )r7   s   "r8   r9   r9   £  s.   € ÷ ñ ¬´­ð Ä%Ì	ÔRUÍÔX\ÐH\ÕB]ñ r:   c           	     óF   € . p\        \        V RRVR7      4      pW!'       * 3# )a  ``home``'s user-installed platform plugin secrets, strictly read, and whether the scan was
complete: False when a plugin dir or flat manifest could not be read or parsed, so the caller
keeps the denials it already knew instead of releasing them on a failed discovery.rÝ  T)rï  rð  )r  r÷  )r·  rð  r
  s   &  r8   Úplatform_manifest_secret_scanr  £  s,   € ð €GÜ!Ô"<¸TÀ6ÐRVÐ`gÔ"hÓi€EØ”+ÐÐr:   c                óH   € V ^8„  d   QhR\         \        ,          R,          /# r)  r  )r7   s   "r8   r9   r9   ¬  s   € ÷ Kñ K¬)´C­.¸4Õ*?ñ Kr:   c                 óÜ  € . p  \        \        RRR7      4      p \        T ;'       g    . 4      pV f   RMR F   p V\        \        VR7      4      ,          pK"  	  V FÕ  w  r4VP	                  R4      ;'       g    VP	                  R4      ;'       g    Tp\        V4       F�  w  rgpV\        9   d   K  RVP	                  R4      ;'       g    V R	2R
VP	                  R
4      ;'       g    TRVP	                  R4      ;'       g    RRTRVP	                  R4      ;'       g    R/\        V&   K�  	  K×  	  V e   \        V 4      # R#   \         d    Rp  EL=i ; i  \         d     EK3  i ; i)aÂ  Populate OPTIONAL_ENV_VARS from platform plugin manifests (bundled AND user-installed) so
Teams / IRC / Google Chat and third-party platforms are configurable in the ``hermes config`` /
Desktop Gateway form without the core knowing they exist. Failures are swallowed so a
malformed plugin.yaml can't break CLI import. Returns the bundled manifests' secret names, or
None when a bundled manifest could not be read (the policy then re-reads strictly).
rÜ  T)rØ  rï  N)rØ  r¹  r  r�  z configurationr:  r\  r=  rÈ  r  )rÜ  rÝ  )rÝ  )r  r÷  r/  rK  rR  r  rÓ  r  )	rÜ  r  rØ  rô  rö  r¹  r  r   rÿ  s	            r8   Ú _inject_platform_plugin_env_varsr  ¬  sj  € ð €GðÜÔ1¸È4ÔPÓQˆô �W—]�] Ó#€IØ)0ªÑ%¸iÒGˆð	ØœÔ8ÀÔGÓHÕHŠIñ Hó
 (ÑˆØ—‘˜WÓ%×IÐI¨¯©°fÓ)=×IÐIÀˆÜ%CÀHÖ%MÑ!ˆD˜TØÔ(Ô(Ùà˜tŸx™x¨Ó6×RÐR¸U¸GÀ>Ð:RØ˜$Ÿ(™( 8Ó,×4Ð4°Ø�t—x‘x “×.Ð.¨$Ø˜IØ˜DŸH™H ZÓ0×?Ð?°Kð'AÔ˜dÓ#ó &Nñ (ð .5Ò-@Ô  Ó)ÐJÀdÐJøô' ô Ø‹ðûô ô 	Ûð	ús"   „E »EÅEÅEÅE+Å*E+c                ó  € V ^8„  d   Qh/ ^ \         9   d   \        \        R3,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d   \        \        \
        3,          ;R&   ^\         9   d(   \        \        \        \        R3,          3,          ;R&   ^\         9   d(   \        \        \        \        R3,          3,          ;R&   ^\         9   d
   \        ;R&   ^\         9   d&   \        \        \        \        ,          3,          ;R&   ^\         9   d   \        \        \
        3,          ;R	&   ^\         9   d   \        \        ,          ;R
&   ^	\         9   d   \        \        ,          R,          ;R&   # )r3   .r´   r²   r»  r½  r+  rÏ  r’  r$  r  Nr  )	Ú__conditional_annotations__r  rD   r  rj  r   r  rà  r  )r7   s   "r8   r9   r9      sB  € ÷ =ñ =÷zò œU¤3¨ 8�_ñ ñ{=÷H 6ò  6œ	¤#�ñ  6ñI=÷L 3Ò 2œt¤C¬ H�~Ñ 2ñM=÷d 4Ò 3”Dœœe¤C¨ H�oÐ-Õ.Ñ 3ñe=÷h 3Ò 2”4œœU¤3¨ 8�_Ð,Õ-Ñ 2ñi=÷b "Ò !”cÑ !ñc=÷R!ò !”Tœ#œt¤C�y˜.Õ)ñ !ñS=÷BQ -Ò ,œœc¤3˜h�Ñ ,ñCQ=÷\~ GÒ Fœ¤3�Ñ Fñ]~=÷^~ YÒ Xœi¬�n¨tÕ3Ñ Xò_~=r:   )ÚLD_ÚDYLD_ÚGIT_CONFIG_>   r$  r8  r7  r  r%  r9  r  r+  )zmodify this Hermes installation)zmodify configuration)
ÚcronÚsessionsÚlogszlogs/curatorÚmemoriesÚpairingÚhooksÚimage_cacheÚaudio_cacheÚskills)rö  r÷  rø  rù  )r  r  ÚWHATSAPP_ALLOWED_USERSrü  rý  ÚSLACK_ALLOWED_USERSr<   >   ÚsignalrÛ  ÚtimeoutsÚ	image_genr©  Ú	video_genrx  rê  Úprofile_routesÚreset_triggersÚallow_all_usersÚrequire_mentionÚalways_log_localr¨  r…  Úmultiplex_profilesÚsmart_model_routingÚstt_echo_transcriptsÚknown_plugin_toolsetsÚknown_builtin_toolsetsÚgroup_sessions_per_userÚfilter_silence_narrationÚthread_sessions_per_userÚunauthorized_dm_behaviorÚtool_gateway_declined_tools>   r  r  ÚmodelsrC  rE  rG  rH  Ú
extra_bodyÚ
ssl_verifyÚssl_ca_certr  Úcatalog_providerÚrate_limit_delay>   rC  rG  rH  r>  rK   ))r  z#Add a name, e.g.: name: my-provider)rH  zDAdd the API endpoint URL, e.g.: base_url: https://api.example.com/v1)©rý  z/Add: provider: openrouter (or another provider))r  zAdd: model: <model-name>)r?  )r  z8Add: model: anthropic/claude-sonnet-4 (or another model))TF>	   rŸ  r  r  r}  ÚinfiniteÚinfinityÚ	unlimitedõ   âˆžú-1)r=   )!Ú
modal_modeÚdegraded_moderˆ  Útemp_dirÚtimeoutÚlifetime_secondsrœ  Údocker_forward_envÚmodal_imageÚdaytona_imageÚvercel_runtimeÚvercel_imageÚssh_hostÚssh_userÚssh_portÚssh_keyÚcontainer_cpuÚcontainer_memoryÚcontainer_diskÚcontainer_persistentÚdocker_volumesÚ
docker_envÚdocker_mount_cwd_to_workspaceÚdocker_networkÚdocker_extra_argsÚdocker_shm_sizeÚdocker_run_as_host_userÚdocker_snap_compatÚdocker_persist_across_processesÚdocker_shared_container_keyÚdocker_orphan_reaperÚsandbox_dirÚpersistent_shell>   Újwtr¥   r‡  ÚapikeyÚbearerÚpasswdrý  rC  Úid_tokenr=  Úprivate_keyÚaccess_tokenÚauthorizationÚclient_secretÚrefresh_token)Ú_api_keyÚ_tokenÚ_secretÚ	_passwordrø  Ú_access_key)Ú_urlÚ_hostÚ_userÚ_idÚ_domainÚ_scheme)r®  >   Úgoalsr   ÚloopsÚsecretsrÚ  rx  Úmodel_catalogÚpersonalitiesÚquick_commandsÚserver_actionsÚchannel_promptsÚcommand_allowlistÚcredential_pool_strategies>   ÚsmsÚemailÚqqbotÚslackÚwecomÚfeishuÚmatrixr&  ÚweixinÚdiscordrÛ  ÚyuanbaoÚdingtalkr  ÚtelegramÚwhatsappÚ
mattermostÚbluebubblesÚcheckpoints)g333333ã?)zhermes config get modelz"hermes config get terminal.backendz&hermes config get skills.config --json)z1hermes config set model anthropic/claude-sonnet-4z)hermes config set terminal.backend dockerz.hermes config set OPENROUTER_API_KEY sk-or-...)rL   z=  --force: skip the unknown-key notice for unrecognized keys,z@           and allow a scalar to replace a whole mapping section)zhermes config unset modelz$hermes config unset terminal.backendz&hermes config unset OPENROUTER_API_KEY)rÔ  rÜ  rÝ  )NrÔ  )rq  rr  Ú_KEYÚ	_PASSWORDÚ_JSON)NrÝ  (~  r  rT   Úhermes_cli.stale_modulesr   r¢  rä  r  Úloggingrv  rÐ  r¾  r  r±  r:  rÒ  rf  rÁ  r%  ÚtimeÚunicodedataÚ
contextlibr   r   Údataclassesr   Údecimalr   r   Úpathlibr	   Útypingr
   r   r   r   r   r   r   Úhermes_yamlr�  Úhermes_cli.cli_outputr   Úhermes_cli.colorsr   r   Ú
hermes_clir   Úhermes_cli.default_soulr   r   Úhermes_cli.secret_promptr   rJ  r   r   r   r   r   r   r   r   r    r!   r"   ra  r#   r$   r%   r&   Úhermes_cli.config_read_errorsr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   Ú	getLoggerrP   r’  r>   rG   rM   r  rO   Úsystemr¨   Úcompiler¯   r´   r  r²   r«   r¶   ÚRLockr;  r»  r½  r+  r£  r!  r>  r  r"  r#  r0  r1  rE  r;  rN  rQ  rS  rV  rY  rZ  r`  rh  r€  r…  r›  rŸ  r:  r¦  r«  rµ  rË  rà  rÏ  rÑ  rÒ  Úhermes_cli.config_defaultsr´  rÓ  Úhermes_cli.config_providersrÔ  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í  rî  rï  Úhermes_cli.personalityrð  Ú_NEUTRAL_PERSONALITY_NAMESrñ  Ú_prompt_textrò  ró  Ú+resolve_ephemeral_system_prompt_from_configÚhermes_cli.config_version_stamprô  rõ  r’  r  r  r  r&  r.  r;  rJ  rø  rR  rO  rT  rX  rs  rv  r„  r—  r§  rÝ  rá  r  Ú_VALID_CUSTOM_PROVIDER_FIELDSrâ  r«  r¶  r¾  rä  rë  rì  rÉ  rÑ  rÙ  rß  ræ  rí  rû  r	  r  r  r'  r3  r8  rA  rJ  rt  re  rf  r�  rg  rj  r¦  r¤  r²  rÐ  r»  rÇ  rÅ  rÄ  rÒ  rÖ  rÚ  rÝ  rí  rù  rþ  r  r  r  Úmaxsizer"  r!  r$  r�  r-  r3  r>  ri  rG  rJ  rQ  rU  rc  rk  rn  r–  ru  rx  r~  r©   r�  r„  r‰  r�  r’  r—  r«  rµ  rÄ  r¼  rÖ  rr  ré  rê  râ  rì  r³  r.  rþ  r  r  rc  r   r$  ÚLockr#  r'  r  r  rE  rM  rU  r]  rd  ri  rm  rb  r@  r~  r„  rŒ  r’  r”  r—  r   r¦  r©  r	  r¯  r·  r¼  r½  r»  rÂ  r¾  rÃ  rÖ  rÙ  Ú_OPEN_DICT_TOP_LEVEL_KEYSÚ_SCHEMA_DEFINED_DICT_KEYSÚ_DYNAMIC_TOP_LEVEL_KEYSrí  rÞ  rß  ræ  rî  rú  r  r  r  r  r  r  r  r  r%  r.  r2  r7  r=  r  rC  rI  rh  ro  rv  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  r  r  r  r  r  r9   )r¥   r  s   0@r8   Ú<module>r·     sÖ  øð÷=ð =õ =á Ô ã Û Û Û Û 	Û Û 	Û Û Û Û Û 
Û Û Û Û ß /Ý !ß -Ý ß A× AÑ Aã å ,ß +Ý $ß LÝ 9÷1÷ 1õ 1÷
 Fß PÓ P÷÷ ÷ ð
 
×	Ò	˜8Ó	$€õõ
õ
ô
O˜\ô Oð �oŠoÓ 9Ñ,€Ø—:’:Ð9Ó:Ð ñ 0Ð ó ñ *3ð  45àð 45à#ð 45à%/ð 45à1;ð 45ð ð 45ð 1ð 45ð 3Hð 45ð !ð	 45ð #Að	 45ð ð 45ð ð 45ð !0ð 45ð 2Bð 45ð ð 45ð +ð 45ð -?ð 45ð AOð 45ð ð 45ð  ð 45ð ð 45ð ð 45ð &ð 45ð (1ð 45ð 3<ð 45ð >Ið 45ð ð 45ð )ð 45ð +=ð 45ð ð 45ð ð 45ð ð 45ð ð 45ð ð 45ð !)ð 45ð +3ð 45ð 5<ð 45ð >Hð 45ð ð 45ð 'ð 45ð )4ð 45ð  ð! 45ð  ð! 45ð  ,ð! 45ð  .<ð! 45ð" ð# 45ð" (ð# 45ð" *5ð# 45ð" 7Jð# 45ð$ ð% 45ð$ ,ð% 45ð$ .7ð% 45ð( ð) 45ð( ð) 45ð( !ð) 45ð( #3ð) 45ð( 5>ð) 45ð( @Hð) 45ð, ð- 45ð, $ð- 45ð, &5ð- 45ð, 7Cð- 45ð. ð/ 45ð. ,ð/ 45ð2 ð3 45ð6 !ð7 45ð6 #<ð7 45ð: ð; 45ð: .ð; 45ð: 0Gð; 45ð< ð= 45ð< ,ð= 45ð< .Fð= 45ð> ð? 45ð> 9ð? 45ð@ ðA 45ð@ 4ðA 45ó  *6Ð ó  6ðF+À4÷ +õð* �ŠÓ €ð 13Ð Ó 2ð 24Ð Ó 3à02Ð Ó 2ñ ð "KØð"KØ'ð"KØ)<ð"KØ>Oð"Kàð"Kà7ð"Kð ð"Kð :ð"Kð ð	"Kð 4ð	"Kð
 ð"Kð
 (ð"Kð
 *@ð"Kð
 B^ð"Kð ð"Kð 6ð"Kð 8Jð"Kð Lcð"Kð ð"Kð 3ð"Kð 5Lð"Kð Njð"Kð ð"Kð )ð"Kð +?ð"Kð A\ð"Kð ð"Kð 6ð"Kð 8Nð"Kð Pkð"Kð ð"Kð #ð"Kð %=ð"Kð ?[ð"Kð ð"Kð  6ð"Kð 8Yð"Kð ð"Kð 1ð"Kð 3Gð"Kð Ibð"Kð ð"Kð (ð"Kð *;ð"Kð =Rð"Kð ð"Kð 6ð"Kð 8Jð"Kð Lað"Kð ð"Kð 9ð"Kð ;Sð"Kð  ð!"Kð  5ð!"Kð  7Qð!"Kð  Srð!"Kð" ð#"Kð" $ð#"Kð" &:ð#"Kð" <Uð#"Kð$ ð%"Kð$ .ð%"Kð& ð'"Kð& 1ð'"Kð& 3Gð'"Kð& I^ð'"Kð( ð)"Kð( (ð)"Kð( *8ð)"Kð* ð+"Kð* ð+"Kð* -ð+"Kð* /<ð+"Kð* >Kð+"Kð* Mbð+"Kð, ð-"Kð, ,ð-"Kð, .@ð-"Kð, BUð-"Kð4  ð5"Kð6 ð7"Kð6 (ð7"Kð8 ð9"Kð8  >ð9"Kð8 @Wð9"Kð: ð;"Kð: +ð;"Kð: -?ð;"Kð: ASð;"Kð< ð="Kð< ;ð="Kð< =Qð="Kð< Sjð="Kð> ð?"KðB ðC"KðB 8ðC"KðB :VðC"KðD ðE"KðD  2ðE"KðD 4JðE"Kó "L€ðN   Ð0Ð ñ �,Ó€
õ,ðsð õUñ 'Ó'jÓkÐ õD÷.ð .õbõ=ð Ð<Ø	Ð%ðÐ õBõ3ðKÐ õ<"÷
Dð D÷;ð ;õ
RõB-ð
!;À÷ !;õH&õ
2ò
)ò 	÷ð õ ñH  ›EÐ Ó !ñ@Ð ò
F÷& IÐ H÷@÷ @÷ @÷ @÷ @÷ @÷ @ô @÷Tô T÷5ð 5ð ÓXØÑ Ñ"6Ð7Øó EàÑ	ÐØÑ	Ðð-!Ð ó !ð Ð ÷	(ò 	(÷÷6÷$
]÷:dñzÙ8<ñÙUYñà ÷ñ ñ4 ‹8€÷÷>÷ñ* ð 
&Ùð
&Ø*ð
&Ø,?ð
&ÙAYð
&áð
&á%ð
&á':ð
&á<Oð
&ñ ð
&ñ 0ð
&ñ 2Ið
&ñ ð	
&ñ 1ð	
&ñ
 ð
&ñ
  0ð
&ñ
 2Fð
&ñ
 HXð
&ñ ð
&ñ 4ð
&ñ 6Kð
&ñ ð
&ñ $ð
&ñ &9ð
&ñ ð
&ñ -ð
&ð /Að
&ñ ð
&ñ 'ð
&ñ ):ð
&ñ ð
&ñ %ð
&ó 
'Ð ÷
1÷
÷÷,]ó4Ð ñ& ˜^×0Ó0Ó2Ó3Ð6LÕLÐ ó!@Ð ó  WÐ ð ÷ò ó ð÷8÷[ò [ñZÐ ñ+Ð ñKÐ ÷
f÷Z÷B
Dñ |€÷Y÷,A÷\÷2÷&:÷.(ò (÷V0ò 0÷"4÷4	÷÷"÷Jò J÷Z#÷<N÷
÷÷,÷6÷÷$ð �jŠj™Ó(€÷÷&÷6K÷
óöó0ö$÷Nð" 8FØ48÷3ñ 3÷00÷R÷j
÷Kð —{’{Ð ñ !ó "Ró SÐ ð 1E÷ 1ñ 1ñ8Àd÷ ñ ÷÷
$÷/6÷d5÷2ò 2÷6÷$ò $÷Nó ñ2cà-1÷cò cñ4
cØY]÷
cò 
cñbØY]÷bò b÷1ð 1÷2ð 2÷ð ñØBG÷ò ñ ˆ~ðIòGó
HñGˆCð 	‰y˜Ÿš›˜Ð&Ò&ñGñ
HðIÑ ÷Pð P÷Sð S÷
Mð M÷hð h÷
]ð ]ñ0Ø'+ñ0ØPTñ0à#÷0ò 0÷fAð A÷(&ð &÷RWð W÷$ð ÷2Vð Vñr	Ñ ñÑ ÷2ð ÷	"ð 	"ñ,<Ù6:ñ,<à48ñ,<àQV÷,<ò ,<÷^
)ð 
)÷	ð 	÷ ð  ÷
ð 
÷ð ÷$2ð 2ð +-Ñ Ó ,Ø )§£Ó 0Ñ ÷Jð Jð öó ñ÷<ð ÷>ð ÷*ð ð:Èt÷ :ò :÷, ð  ÷:
ð 
÷ð ÷"ð "÷Lð L÷ð ÷8Pð P÷ð ó,ÑZ^÷ ó ÷/ó /÷
,÷
Bó B÷
	Cð 	C÷ð ÷"	ð 	÷7ð 7÷+ð +÷$Bð Bñ  ó !$ó %Ñ ñ dÑ ñ SÑ Ø—j’jÑ!BÓCÑ ÷Uð U÷ó ô&<÷24ð 4ñ &ó '!ó "Ñ ñ &ó 'ó Ñ ñ $Ùð%ó Ñ ñ %¡k ]Ó3Ñ ñ 8Ñ:QÕQÑTmÕmÑ ÷Vð V÷dó d÷
?ð ?÷Dð ÷(ð ÷*ð ÷	ð 	ñ ‰D‘%™™t¡TÙˆU‘D˜%¡¨ñ ˆD‘&˜$¡ Tð+�÷"ð "ñP ™Ù‘Ù‘YÙ‘Yñ ‘vÙ™Ù&©ð
Ñ ñ !*Ñ+DÑFWÐ*XÓ YÑ ÷ð ÷$+ð +÷,Yð Y÷Dð ÷ð ÷	ð 	÷ð ÷
Pð P÷Ið I÷"G3ó G3ñT2^°%ñ 2^ÀU÷ 2^ò 2^÷j61ð 61÷vó ÷$ð $ñ @ó B.à/3ð5�
ñ Aó C6ó8HðI�
ñ
 3ó 5.à/3ð5�ô
gôZô0÷=ð =÷
ð ô%ôP#÷Lð ð 	Ò
)Ù
Ò+Ù
Ò&Ù	‰?Ù	‰?ÙÑÙ
Ò1ÙÒ2ÙÑ"ÙÑð
 Ñ ñ	1�ô
÷ð ò0 Ô ð !Ñ!9Õ:Ñ ÷?ð ?÷)ó )÷XVó Vó%!Ø.3ñ%!ØLP÷%!ó %!ñR  SÑ ñ$Át÷ $ò $÷ Kð KóZØ16÷Zó Z÷ó ÷Kð KñF +4Ð4EÓ*FÑ Ó FÚ6VÓ6XÑ Õ XùòE<
Hs   Ý4q!