+
    jHàjab  ã                  óò  € R t ^ RIHt ^ RIt^ RIt^ RItR tRRRRRR	R
RR. RVO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RRRRR/RR RR!RRRR"/./.tR# R$ ltR% R& lt	R' R( lt
R) R* ltR+ R, ltR- R. ltR/ R0 ltR1 R2 ltRRWRRX/tR3 R4 ltR5 R6 ltR7 R8 ltR9 R: ltR; R< ltR= R> ltR? R@ ltRA RB ltRCRRDR/RE RF lltRYtRGRGRHRHRCRI/tRJRZRKR[RLR\/tRM RN ltRO RP ltRQ RR ltRS RT lt RU t!R# )]aW  Gateway platform setup wizard (hermes gateway setup): platform registry/status table, per-platform setup prompts, service offer.

Extracted from ``hermes_cli/gateway.py``. Bodies read facade helpers through ``_gw()`` (late
binding on ``hermes_cli.gateway``) so the seams tests and callers patch on the facade keep
intercepting the moved code.
)ÚannotationsNc                 ó   € ^ RI Hp  V # )é    ©Úgateway)Ú
hermes_clir   r   s    ÚD/home/ubuntu/.hermes/hermes-agent/hermes_cli/gateway_setup_wizard.pyÚ_gwr	      s
   € Ý"Ø€Nó    ÚkeyÚ
mattermostÚlabelÚ
MattermostÚemojiu   ðŸ’¬Ú	token_varÚMATTERMOST_TOKENÚsetup_instructionsÚvarsÚnameÚMATTERMOST_URLÚpromptz(Server URL (e.g. https://mm.example.com)ÚpasswordFÚhelpz@Your Mattermost server URL. Works with any self-hosted instance.z	Bot tokenTz&Paste the bot token from step 2 above.ÚMATTERMOST_ALLOWED_USERSz"Allowed user IDs (comma-separated)Úis_allowlistz*Your Mattermost user ID from step 4 above.ÚMATTERMOST_HOME_CHANNELzVHome channel ID (for cron/notification delivery, or empty to set later with /set-home)z@Channel ID where Hermes delivers cron results and notifications.ÚMATTERMOST_REPLY_MODEuT   Reply mode â€” 'off' for flat messages, 'thread' for threaded replies (default: off)zFoff = flat channel messages, thread = replies nest under your message.c               ó   € V ^8„  d   QhRR/# )é   Úreturnz
list[dict]© )Úformats   "r   Ú__annotate__r"   5   s   € ÷ ñ ˜
ñ r
   c                 ó*  €  ^ RI Hp  V ! 4        \        P                  R8H  p\        4       P                   Uu. uF-  q2'       d   VP                  R4      R8X  d   K"  \        V4      NK/  	  ppV Uu/ uF  q3R,          VbK  	  pp ^ RIHp TP                  4        F™  pTP                  T9   g   T'       d   TP                  R8X  d   K/  TP                  RTP                  RTP                   R	TP"                  R
TP$                  '       d   TP$                  ^ ,          MRRTP&                  RT/4       K›  	  T#   \         d0   p\        4       P                  P                  RT4        Rp?ELaRp?ii ; iu upi u upi   \         d    Tu # i ; i)aY  Built-in ``_PLATFORMS`` plus registry plugin platforms (same dict shape, source in
``_registry_entry``). Plugins are discovered here (idempotent) so the setup menu works without a
running gateway; user-installed ones still need ``plugins.enabled`` (untrusted code). Matrix is
hidden on Windows: python-olm has no wheel or native build (use WSL).)Údiscover_pluginsz7plugin discovery failed during platform enumeration: %sNÚwin32r   Úmatrix)Úplatform_registryr   r   r   Ú Úinstall_hintÚ_registry_entry)Úhermes_cli.pluginsr$   Ú	Exceptionr	   ÚloggerÚdebugÚsysÚplatformÚ
_PLATFORMSÚgetÚdictÚgateway.platform_registryr'   Úall_entriesr   Úappendr   r   Úrequired_envr)   )r$   ÚeÚhide_matrixÚpÚ	platformsÚby_keyr'   Úentrys           r   Ú_all_platformsr>   5   sZ  € ð
YÝ7ÙÔô —,‘, 'Ñ)€KÜ"%£%×"2Ò"2ÓeÑ"2˜Q¾;È1Ï5É5ÐQVË<Ð[cÑKc””�a–Ñ"2€IÐeÙ#,Ó-¡9˜a��h˜Šk¡9€FÐ-ðÝ?ð #×.Ñ.Ö0ˆØ�:‰:˜Ô§K°E·J±JÀ(Ô4JÙØ×ÑØ�5—:‘:˜w¨¯©°W¸e¿k¹kØ°%×2D×2DÐ2D˜×+Ñ+¨AÖ.È"Ø˜E×.Ñ.Ð0AÀ5ð
ö 	ñ 1ð Ðøô) ô YÜ‹�‰×ÑÐTÐVW×XÒXûðYüò fùÚ-øô ô ØÒðús:   ‚D; ¸E8ÁE8Á1E=ÂF Ä;E5Å$E0Å0E5ÆFÆFc               ó    € V ^8„  d   QhRRRR/# )r   r0   r3   r   Ústrr    )r!   s   "r   r"   r"   T   s   € ÷ Pñ P˜tð P¨ñ Pr
   c                óŠ  € V P                  R4      pVe^    VP                  e)   ^ RIHp \	        VP                  V! RR7      4      4      pM\	        VP                  4       4      p V'       d   R# R# V P                  RR	4      pV'       g   R# \        4       P                  V4      '       d   R# R#   \         d    Rp LZi ; i)
zTPlain-text status string; uncolored because ANSI codes break curses menu width math.r*   )ÚPlatformConfigT)ÚenabledFÚ
configuredúnot configuredr   r(   )	r2   Úis_connectedÚgateway.configrB   ÚboolÚcheck_fnr,   r	   Úget_env_value)r0   r=   rB   rD   r   s   &    r   Ú_platform_statusrK   T   s°   € à�L‰LÐ*Ó+€EØÒð	Ø×!Ñ!Ò-Ý9Ü! %×"4Ñ"4±^ÈDÔ5QÓ"RÓS‘
ä! %§.¡.Ó"2Ó3‘
÷  *ˆ|Ð?Ð/?Ð?à—‘˜[¨"Ó-€IßÙÜ›5×.Ñ.¨y×9Ò9ˆ<ÐOÐ?OÐOøô ô 	ØŠJð	ús   —5B2 ÁB2 Â2CÃCc               ó$   € V ^8„  d   QhRRRRRR/# )r   Úplatform_keyr@   Úbehaviorr   ÚNoner    )r!   s   "r   r"   r"   j   s'   € ÷ dñ d¸ð dÈð dÐPTñ dr
   c                ó@   € \        4       P                  V RVRR7       R# )zBPersist a platform-specific unauthorized-DM policy in config.yaml.Úunauthorized_dm_behaviorT)ÚrawN)r	   Úwrite_platform_config_field)rM   rN   s   &&r   Ú&_set_platform_unauthorized_dm_behaviorrT   j   s   € äƒE×%Ñ% lÐ4NÐPXÐ^bÐ%Öcr
   c               ó    € V ^8„  d   QhRRRR/# )r   Útitler@   r   rO   r    )r!   s   "r   r"   r"   o   s   € ÷ Rñ R˜cð R dñ Rr
   c                ó    € \        4        \        \        4       P                  R V  R2\        4       P                  P                  4      4       R# )u     â”€â”€â”€ u    Setup â”€â”€â”€N)Úprintr	   ÚcolorÚColorsÚCYAN)rV   s   &r   Úprint_setup_headerr\   o   s2   € Ü	„GÜ	Œ#‹%�+‰+˜ U GÐ+;Ð<¼c»e¿l¹l×>OÑ>OÓ
PÖQr
   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r@   Úenv_varsr   rH   r    )r!   s   "r   r"   r"   t   s!   € ÷ ñ ˜sð ¨sð °tñ r
   c                ó  € \         ;QJ d    R V 4       F  '       d   K   RM	  RM! R V 4       4      '       dE   \        4        \        4       P                  V  R24       \        4       P	                  RV  R2R4      # R# )zXFalse when ``label`` is already configured (all ``env_vars`` set) and the user declines.c              3  óT   "  € T F  p\        4       P                  V4      x € K   	  R # 5i©N)r	   rJ   )Ú.0Úvs   & r   Ú	<genexpr>Ú&confirm_reconfigure.<locals>.<genexpr>v   s    é € Ð
4©8 aŒ3‹5×Ñ˜q×!Ð!«8ùs   ‚&(FTz is already configured.z  Reconfigure Ú?)ÚallrX   r	   Úprint_successÚprompt_yes_no)r   r^   s   &*r   Úconfirm_reconfigurerj   t   sa   € ç
ƒsÑ
4©8Ó
4‡s‡s‚sÑ
4©8Ó
4×4Ò4ÜŒÜ‹×Ñ˜u˜gÐ%<Ð=Ô>Ü‹u×"Ñ" ^°E°7¸!Ð#<¸eÓDÐDÙr
   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úhome_varr@   Úuser_idÚwhatr   rO   r    )r!   s   "r   r"   r"   }   s.   € ÷ @ñ @ ð @¨sð @¸#ð @À$ñ @r
   c                óÂ   € \        4       P                  RV RV R2R4      '       d8   \        4       P                  W4       \        4       P                  RV 24       R# R# )zLOffer to persist ``user_id`` as ``home_var`` (e.g. "your Telegram user ID").z  Use z (z) as the home channel?Tz  Home channel set to N)r	   ri   Úsave_env_valuerh   )rl   rm   rn   s   &&&r   Úoffer_home_channelrq   }   sU   € ä
ƒu×Ñ˜V D 6¨¨G¨9Ð4JÐKÈT×RÒRÜ‹×Ñ˜XÔ/Ü‹×ÑÐ4°W°IÐ>Ö?ñ Sr
   c               ó    € V ^8„  d   QhRRRR/# )r   Úvaluesr@   r   rO   r    )r!   s   "r   r"   r"   „   s   € ÷ *ñ *˜cð * dñ *r
   c                 ój   € V P                  4        F  w  r\        4       P                  W4       K   	  R # ra   )Úitemsr	   rp   )rs   r   Úvalues   ,  r   Úsave_env_valuesrw   „   s$   € Ø—|‘|–~‰ˆÜ‹×Ñ˜TÖ)ó &r
   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úprompt_textr@   Údefaultr   r    )r!   s   "r   r"   r"   ‰   s&   € ÷ Oñ O˜Cð O¨#ð O°#ñ Or
   c                óX   € \        4       P                  WRR7      P                  RR4      # )z3Comma-separated ID prompt with whitespace stripped.F©r   Ú r(   )r	   r   Úreplace)ry   rz   s   &&r   Ú
prompt_csvr   ‰   s$   € ä‹5�<‰<˜°uˆ<Ó=×EÑEÀcÈ2ÓNÐNr
   c               ó    € V ^8„  d   QhRRRR/# )r   rM   r@   r   rO   r    )r!   s   "r   r"   r"   �   s   € ÷ Vñ V¨cð V°dñ Vr
   c                ór  € V R8H  p\        4        \        V,          vr#\        4       P                  RW24      pV^ 8X  d@   \        4       P	                  V'       d   RMRR4       \        4       P                  R4       R# V^8X  dI   V'       d   \        RR4       \        4       P                  R4       \        4       P                  R	4       R# V^8X  d(   \        V R
4       \        4       P                  R4       R# V'       d   \        4       P                  R4       R# \        4       P                  R4       R# )u`   No allowlist was given â€” ask open access vs DM pairing vs decline vs skip/silent, and persist.Úemailz+  How should unauthorized users be handled?ÚEMAIL_ALLOW_ALL_USERSÚGATEWAY_ALLOW_ALL_USERSÚtrueu2     Open access enabled â€” anyone can use your bot!ÚpairuB     DM pairing mode â€” users will receive a code to request access.z8  Approve with: hermes pairing approve <platform> <code>Údeclinez[  Unknown senders get one polite decline, then silence (unauthorized_dm_behavior: decline).z(  Unknown email senders will be ignored.u9     Skipped â€” configure later with 'hermes gateway setup'N)	rX   Ú_UNAUTHORIZED_ACCESS_CHOICESr	   Úprompt_choicerp   Úprint_warningrT   rh   Ú
print_info)rM   Úis_emailÚdefault_idxÚaccess_choicesÚ
access_idxs   &    r   Ú_prompt_unauthorized_accessr�   �   sâ   € à˜wÑ&€HÜ	„GÜ#?ÀÕ#IÐ €KÜ“×$Ñ$Ð%RÐTbÓp€JØ�Q„Ü‹×Ñ¿Ñ4ÐF_ÐagÔhÜ‹×ÑÐPÖQØ	�qŒßÜ2°7¸FÔCÜ‹×ÑÐ`ÔaÜ‹×ÑÐSÖTØ	�qŒÜ.¨|¸YÔGÜ‹×ÑÐyÖzß	Ü‹×ÑÐFÖGä‹×ÑÐTÖUr
   c               ó    € V ^8„  d   QhRRRR/# )r   r   r@   r   ztuple[bool, object]r    )r!   s   "r   r"   r"   ´   s   € ÷ ñ  Cð Ð,?ñ r
   c                ó„  € \        4        \        4       P                  RRR4       \        4       P                  RRR7      P	                  4       R8w  d   R#  ^ RIHpHp T! 4       pT'       dc   T! TP                  4      '       dK   \        4       P                  YP                  4       \        4       P                  R	4       R
TP                  3# T'       d   \        4       P                  R4       \        4        \        4       P                  R4       R#   \         d    \        4       P                  R4       Ru # i ; i)zDOffer the managed-bot QR flow. Returns (token_saved, owner_user_id).z>  Telegram can be configured automatically with a managed bot:u:     [1] Automatic (scan QR â†’ confirm in Telegram â†’ done)z  [2] Manual BotFather tokenz  Choice [1/2]Ú1)rz   )Úauto_setup_telegram_bot_resultÚis_valid_telegram_bot_tokenz1  Automatic setup is unavailable in this install.z  Saved TELEGRAM_BOT_TOKENTz5  Automatic setup returned an invalid Telegram token.z!  Falling back to manual setup...)FN)rX   r	   Ú_print_info_linesr   ÚstripÚhermes_cli.telegram_managed_botr”   r•   ÚImportErrorrŠ   Útokenrp   rh   Úowner_user_idr‹   )r   r”   r•   Úresults   &   r   Ú_telegram_auto_setupr�   ´   sý   € ä	„GÜƒE×ÑØHØDÐFdôô ƒu‡|�|Ð$¨c€|Ó2×8Ñ8Ó:¸cÔAØÐð÷	
ñ ,Ó-€FßÑ-¨f¯l©l×;Ò;Ü‹×Ñ˜Y¯©Ô5Ü‹×ÑÐ8Ô9Ø�V×)Ñ)Ð)Ð)ßÜ‹×ÑÐSÔTÜ	„GÜƒE×ÑÐ8Ô9ØÐøô ô Ü‹×ÑÐOÔPØÒðús   ÁD Ä&D?Ä>D?c               ó    € V ^8„  d   QhRRRR/# )r   Úcleanedr@   r   r    )r!   s   "r   r"   r"   Ð   s   € ÷ ñ  ð ¨ñ r
   c                ó¦  € . pV P                  R4       Fª  pVP                  4       pVP                  R4      '       d8   VP                  R4      '       d!   VP	                  R4      P                  R4      pVP                  4       P                  R4      '       d
   VR,          pV'       g   K™  VP                  V4       K¬  	  RP                  V4      # )zVStrip common Discord prefixes (user:123, <@123>, <@!123>) from a comma-separated list.Ú,z<@Ú>z<@!zuser::é   NN)	Úsplitr—   Ú
startswithÚendswithÚlstripÚrstripÚlowerr6   Újoin)rŸ   ÚpartsÚuids   &  r   Ú_clean_discord_idsr­   Ð   sœ   € à€EØ�}‰}˜SÖ!ˆØ�i‰i‹kˆØ�>‰>˜$×Ò C§L¡L°×$5Ò$5Ø—*‘*˜UÓ#×*Ñ*¨3Ó/ˆCØ�9‰9‹;×!Ñ! '×*Ò*Ø�b•'ˆCß‰3Ø�L‰L˜Öñ "ð �8‰8�E‹?Ðr
   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úvarr3   rM   r@   r   z
str | Noner    )r!   s   "r   r"   r"   Þ   s!   € ÷ ñ ˜tð °3ð Èzñ r
   c                ó¢  € RV R,          9   Ed   V'       dþ   \        V4      p\        4       P                  RV 24       \        4       P                  RR4      '       d·   \        4       P	                  RRR7      pV.pVP                  R	R
4      P                  R4       F&  pV'       g   K  We9  g   K  VP                  V4       K(  	  RP                  V4      p\        4       P                  V R,          V4       \        4       P                  R4       V# \        4       P                  RRR4       \        4       P	                  RV R,           2RR7      pV'       g   \        V4       R# VP                  R	R
4      pRV R,          9   d   \        V4      p\        4       P                  V R,          V4       \        4       P                  R4       V# )zYAllowlist prompt for one var; returns the saved value or None (open-access prompt shown).ÚTELEGRAMr   z"  Detected your Telegram user ID: z-  Allow this Telegram account to use the bot?Tz9  Additional allowed user IDs (comma-separated, optional)Fr|   r}   r(   r¡   u7     Saved â€” only these users can interact with the bot.z7  The gateway DENIES all users by default for security.z7  Enter user IDs to create an allowlist, or leave emptyz-  and you'll be asked about open access next.ú  r   NÚDISCORD)r@   r	   rh   ri   r   r~   r¤   r6   rª   rp   r–   r�   r­   )	r¯   rM   Úauto_owner_user_idÚdetected_idÚextraÚidsr¬   rŸ   rv   s	   &&&      r   Ú_prompt_allowlist_varr¸   Þ   sq  € à�S˜•[Õ ×%7ÜÐ,Ó-ˆÜ‹×ÑÐ@ÀÀÐNÔOÜ‹5×ÑÐNÐPT×UÒUÜ“E—L‘LÐ!\Ðgl�LÓmˆEØ�-ˆCØ—}‘} S¨"Ó-×3Ñ3°CÖ8�ß‘3˜3ž>Ø—J‘J˜s–Oñ 9ð —h‘h˜s“mˆGÜ‹E× Ñ   V¥¨gÔ6Ü‹E×ÑÐ YÔZØˆNäƒE×ÑØAØAØ7ôô
 ‹E�L‰L˜2˜c (�m˜_Ð-¸ˆLÓ>€EßÜ# LÔ1ÙØ�m‰m˜C Ó$€GØ�C˜•KÔÜ$ WÓ-ˆÜƒE×Ñ˜˜V� gÔ.ÜƒE×ÑÐQÔRØ€Nr
   c               ó   € V ^8„  d   QhRR/# )r   r0   r3   r    )r!   s   "r   r"   r"   ÿ   s   € ÷ >8ñ >8 tñ >8r
   c                óà  € ^ RI Hp V R,          V R,          V R,          rCp\        V RV 24       V P                  R4      pV'       d*   \	        4        \        4       P                  ! R V 4       !   \        W44      '       g   R# R	RrvV P                  R
4      R8X  d   \        V4      w  rgRpV R,           U	u. uFA  p	V	R,          V8X  g/   V	P                  R4      '       g   V! V	R,          4      '       d   K?  V	NKC  	  p
p	V
 EF¹  p\	        4        \        4       P                  RVR,           24       \        4       P                  VR,          4      pV'       d+   VR,          V8w  d   \        4       P                  RV 24       V'       d*   VR,          V8X  d   \        4       P                  R4       K´  VP                  R4      '       d$   \        W°P                  R
4      V4      pVe   TpKî  \        4       P                  RVR,           2VP                  RR	4      R7      pV'       dH   \        4       P                  VR,          V4       \        4       P                  RVR,           24       EKr  VR,          V8X  d!   \        4       P                  RV R24        R# \        4       P                  R4       EK¼  	  VP!                  4        R2p\        4       P                  V4      pV'       dK   V'       gC   VR8X  d<   VP#                  R4      ^ ,          P%                  4       pV'       d   \'        VVR4       \	        4        \        4       P                  V RV R24       R# u up	i )z2Interactive setup for Telegram, Discord, or Slack.)Úis_setup_hidden_envr   r   r   r}   r   c              3  ó,   "  € T F
  pR V 2x € K  	  R# 5i)r²   Nr    )rb   Úlines   & r   rd   Ú+_setup_standard_platform.<locals>.<genexpr>  s   é € Ð!G¹,°$ B t f¥+»,ùs   ‚NFr   Útelegramr   r   r   r²   r   z  Current: z!  Token saved by automatic setup.r   r   r|   z  Saved u     Skipped â€” z won't work without this.z  Skipped (can configure later)Ú_HOME_CHANNELÚTelegramr¡   zyour user IDz configured!)Úhermes_cli.setup_hidden_envr»   r\   r2   rX   r	   r–   rj   r�   r‹   rJ   r¸   r   rp   rh   rŠ   Úupperr¤   r—   rq   )r0   Ú_is_setup_hidden_envr   r   r   ÚinstructionsÚauto_token_savedr´   Úallowed_val_setrc   Ú
setup_varsr¯   ÚexistingÚsavedrv   rl   Úhome_valÚfirst_ids   &                 r   Ú_setup_standard_platformrÍ   ÿ   sÇ  € åWØ& wÕ/°¸'Õ1BÀHÈ[ÕDY�)€EÜ˜%˜  % Ð)Ô*à—<‘<Ð 4Ó5€LßÜŒÜ‹×ÒÑ!G¹,Ó!GÒHä˜u×0Ò0Ùà+0°$Ð(Ø‡|�|�EÓ˜jÔ(Ü/CÀIÓ/NÑ,Ðà€Oð ˜FÖ#óÙ#ˆaØˆV�9˜	Ô! Q§U¡U¨>×%:Ò%:ÑBVÐWXÐY_ÕW`×Ba÷ 	
ˆÑ#ð ð ô
 ˆÜŒÜ‹×Ñ˜2˜c &�k˜]Ð+Ô,Ü“5×&Ñ& s¨6¥{Ó3ˆß˜˜F� yÔ0Ü‹E×Ñ˜{¨8¨*Ð5Ô6ç  F¥¨yÔ 8Ü‹E×ÑÐ@ÔAÙà�7‰7�>×"Ò"Ü)¨#¯|©|¸EÓ/BÐDVÓWˆEØÒ Ø"'�Ùä“—‘˜r # h¥- Ð1¸C¿G¹GÀJÐPUÓ<V�ÓWˆßÜ‹E× Ñ   V¥¨eÔ4Ü‹E×Ñ (¨3¨v­;¨-Ð 8×9Ø��[˜IÔ%Ü‹E×Ñ .°°Ð7PÐ QÔRÚä‹E×ÑÐ>×?ñ3 ð8 —+‘+“-� Ð.€HÜ‹u×"Ñ" 8Ó,€HßŸx¨E°ZÔ,?Ø"×(Ñ(¨Ó-¨aÕ0×6Ñ6Ó8ˆßÜ˜x¨°>ÔBä	„GÜƒE×Ñ˜5˜'  5 '¨Ð6Ö7ùòSs   Â9)M+Ã#M+Ã:M+c               ó   € V ^8„  d   QhRR/# )r   r   r@   r    )r!   s   "r   r"   r"   @  s   € ÷ ñ ˜3ñ r
   c                ól   € ^ RI Hp R\        4       P                  P                  /P                  V 4      # )z]Resolve a built-in platform's setup function; late-bound to dodge the hermes_cli.setup cycle.)ÚsetupÚwebhooks)r   rÐ   r	   Úsetup_platformsÚ_setup_webhooksr2   )r   Ú_ss   & r   Ú_builtin_setup_fnrÕ   @  s/   € å&ð 	”C“E×)Ñ)×9Ñ9ð÷ 
�cˆ#ƒhðr
   c               ó    € V ^8„  d   QhRRRR/# )r   r0   r3   r   rO   r    )r!   s   "r   r"   r"   I  s   € ÷ :ñ : $ð :¨4ñ :r
   c                óÀ  € V P                  R4      pVe   VP                  MRpVf   \        V R,          4      pVe
   V! 4        R# V P                  R4      '       d   \        4       P	                  V 4       R# V P                  RV R,          4      p\        V P                  RR4       RV 24       V'       d   VP                  M. pV'       d-   \        4       P                  R	R
P                  V4       24       M&\        4       P                  RV RV R,           24       V P                  R4      '       d&   \        4       P                  RV R,           24       R# R# )z²Plugin ``setup_fn`` -> built-in by key -> ``_setup_standard_platform`` (``vars``) -> env-var hint.
Bundled plugins auto-load; user plugins must already be in ``plugins.enabled``.r*   Nr   r   r   r   u   ðŸ”Œr}   z(  Set these env vars in ~/.hermes/.env: z, z  Configure z( in config.yaml under gateway.platforms.r)   r²   )	r2   Úsetup_fnrÕ   r	   rÍ   r\   r7   r‹   rª   )r0   r=   Úfnr   Úrequireds   &    r   Ú_configure_platformrÛ   I  s#  € ð �L‰LÐ*Ó+€EØ Ò,ˆ�Š°$€BØ	‚zÜ˜x¨�Ó/ˆØ	‚~Ù
ŒÙØ‡|�|�F×ÒÜ‹×&Ñ& xÔ0Ùà�L‰L˜ (¨5¥/Ó2€EÜ˜(Ÿ,™, w°Ó7Ð8¸¸%¸ÐAÔBß%*ˆu×!Ò!°€HßÜ‹×ÑÐCÀDÇIÁIÈhÓDWÐCXÐYÕZä‹×Ñ˜<¨ wÐ.VÐW_Ð`eÕWfÐVgÐhÔiØ‡|�|�N×#Ò#Ü‹×Ñ˜2˜h ~Õ6Ð7Ð8Ö9ñ $r
   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úactionr@   ÚquestionÚfailed_labelr   rO   r    )r!   s   "r   r"   r"   b  s/   € ÷ Qñ Q¨ð Q¸ð QÈ3ð QÐ]añ Qr
   c                ó2  € \        4       P                  4       '       d:   \        4       P                  4       '       d   \        4       P                  V 4       R# \        4       P	                  VR4      '       d    \        4       P
                  ! V 3RV/VB  R# R# )zZWizard start/restart prompt; prints remediation instead when system scope would need root.Trß   N)r	   Úsupports_systemd_servicesÚ$_system_scope_wizard_would_need_rootÚ_print_system_scope_remediationri   Ú_setup_service_action)rÝ   rÞ   rß   Úkwargss   &&&,r   Ú_wizard_offer_service_actionræ   b  sg   € ä
ƒu×&Ñ&×(Ò(¬S«U×-WÑ-W×-YÒ-YÜ‹×-Ñ-¨fÖ5Ü	‹×	Ñ	˜X t×	,Ò	,Ü‹×#Ò# FÑP¸ÐPÈÔPñ 
-r
   ÚwindowsÚsystemc          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   rÝ   r@   rß   rç   rH   rè   r   rO   r    )r!   s   "r   r"   r"   j  s4   € ÷ 4ñ 4Øð4Ø"%ð4Ø04ð4ØEIð4à	ñ4r
   c               ó  €  \        4       P                  VR7      pVe&   \        4       P                  Y@V R8X  d   RMT4       R# V R8X  d>   V'       d4   \        4       P                  4        \        4       P	                  R4       R# R# R#   \        4       P
                   dK   p\        4       P                  RT R24       \        4       P                  \        T4      4        Rp?R# Rp?i\        4       P                   dD   p\        4       P                  RT RT 24       \        4       P                  T 4        Rp?R# Rp?i\        P                   d+   p\        4       P                  RT RT 24        Rp?R# Rp?ii ; i)zÀRun a wizard service start/restart, printing remediation instead of raising. ``windows=False``
skips Windows (pre-platform status block never offers it); ``system`` is a fresh install's scope.©rç   NÚrestartzStart manually: hermes gatewayr²   u     â€” user systemd not reachable:z: )r	   Ú_service_backendÚ_service_callÚstop_profile_gatewayr‹   ÚUserSystemdUnavailableErrorÚprint_errorÚ_print_indentedr@   ÚSystemScopeRequiresRootErrorrã   Ú
subprocessÚCalledProcessError)rÝ   rß   rç   rè   Úbackendr8   s   &$$$  r   rä   rä   j  s*  € ð
4Ü“%×(Ñ(°Ð(Ó9ˆØÒÜ‹E×Ñ ¸À9Ô9L±ÐRXÖYØ�yÔ §WÜ‹E×&Ñ&Ô(Ü‹E×ÑÐ=Ö>ñ &-Ñ øô ‹5×,Ñ,ô &Ü‹×Ñ˜B˜|˜nÐ,LÐMÔNÜ‹×Ñœc !›f×%Ò%ûÜ‹5×-Ñ-ô 6ä‹×Ñ˜B˜|˜n¨B¨q¨cÐ2Ô3Ü‹×-Ñ-¨f×5Ò5ûÜ×(Ñ(ô 4Ü‹×Ñ˜B˜|˜n¨B¨q¨cÐ2×3Ò3ûð4úsB   ‚AB ÁB Á1B ÂFÂ$?C)Ã)FÄ8EÅFÅFÅF Æ FÚsystemdÚlaunchdzScheduled TaskÚwslÚtermuxÚunsupportedc               ó   € V ^8„  d   QhRR/# ©r   r   rO   r    )r!   s   "r   r"   r"   Ÿ  s   € ÷ Yñ Y dñ Yr
   c                 ó  € \        4        \        4       P                  4       p \        4       P                  4       p\        4       P	                  4       '       dA   \        4       P                  4       '       d#   \        4       P                  4        \        4        \        4       P	                  4       '       dA   \        4       P                  4       '       d#   \        4       P                  4        \        4        V '       d$   V'       d   \        4       P                  R4       R
# V '       d+   \        4       P                  R4       \        RRRRR7       R
# \        4       P                  R4       \        4       P                  R	4       R
# )z\Pre-platform service status: warnings, then offer to start an installed-but-stopped service.z)Gateway service is installed and running.z-Gateway service is installed but not running.Ústartz  Start it now?zFailed to startFrë   z%Gateway service is not installed yet.z<You'll be offered to install it after configuring platforms.N)rX   r	   Ú_is_service_installedÚ_is_service_runningrá   Úhas_conflicting_systemd_unitsÚ$print_systemd_scope_conflict_warningÚhas_legacy_hermes_unitsÚprint_legacy_unit_warningrh   rŠ   ræ   r‹   )Úservice_installedÚservice_runnings     r   Ú_wizard_service_status_blockr  Ÿ  sí   € ä	„GÜ›×3Ñ3Ó5ÐÜ“e×/Ñ/Ó1€Oä
ƒu×&Ñ&×(Ò(¬S«U×-PÑ-P×-RÒ-RÜ‹×2Ñ2Ô4ÜŒä
ƒu×&Ñ&×(Ò(¬S«U×-JÑ-J×-LÒ-LÜ‹×'Ñ'Ô)ÜŒçŸ_Ü‹×ÑÐGÖHß	Ü‹×ÑÐKÔLÜ$ WÐ.?ÐARÐ\a×bä‹×ÑÐ@ÔAÜ‹×ÑÐWÖXr
   c               ó   € V ^8„  d   QhRR/# rý   r    )r!   s   "r   r"   r"   ·  s   € ÷ 
5ñ 
5˜tñ 
5r
   c            
     ó²  €  \        4        \        4       P                  R4       \        4       P                  4       p V  Uu. uF$  qR,           RVR,           R\	        V4       R2NK&  	  upR.,           p\        4       P                  RV\        V4      ^,
          4      pV\        V 4      8X  d   R	# \        4       P                  W,          4       KÓ  u upi )
TzMessaging Platformsr   r}   r   z  (Ú)ÚDonezSelect a platform to configure:N)rX   r	   Úprint_headerr>   rK   r‰   ÚlenrÛ   )r;   r:   Ú
menu_itemsÚchoices       r   Ú_wizard_platform_loopr  ·  s·   € Ø
ÜŒÜ‹×ÑÐ0Ô1ä“E×(Ñ(Ó*ˆ	ÙU^Ó_ÑU^ÐPQ˜7�˜ A a¨¥j \°Ô5EÀaÓ5HÐ4IÈÓKÑU^Ñ_ÐciÐbjÕjˆ
Ü“×$Ñ$Ð%FÈ
ÔTWÐXbÓTcÐfgÕTgÓhˆØ”S˜“^Ô#ÙÜ‹×!Ñ! )Õ"3Ö4ùò	 `s   Á*Cc               ó    € V ^8„  d   QhRRRR/# )r   rö   r@   r   rO   r    )r!   s   "r   r"   r"   Ä  s   € ÷ +Kñ +K Sð +K¨Tñ +Kr
   c                ó’  € \        4       P                  4       '       d   RMRp\        4       P                  RR4      p\        4       P                  R\        V ,           RV 2R4      pV'       g�   V'       g…   \        4       P	                  R4       \        4       P	                  R4       \        4       P                  4       '       d   \        4       P	                  R	4       \        4       P	                  R
4       R#  RRrTV R8X  d   \        4       P                  RVR7      w  rEMNV R8X  d   \        4       P                  RVR7       M+\        4       P                  4       P                  RW#R7       R# \        4        V'       d,   V'       d"   \        4       P                  RRVR8H  R7       R# R# R#   \        P                   dA   p\        4       P                  RT 24       \        4       P	                  R4        Rp?R# Rp?i\         d7    \        4       P!                  R4       \        4       P	                  R4        R# i ; i)a­  Fresh install from the wizard: ask start-now / start-on-login once, install, then start.

The Windows installer owns its start decision (Scheduled Task and Startup-folder
paths start the gateway themselves when start_now is true, and a UAC hand-off
installs and starts in the elevated child), so the wizard forwards the answers
and returns without a second start. Each install-intent question is asked exactly
once per setup run.z. (note: services may not survive WSL restarts)r(   z  Start the gateway now?Tz5  Start the gateway automatically on login/boot as a z	 service?z%  Skipped start and auto-start setup.z/  You can install later: hermes gateway installzA  Or as a boot-time service: sudo hermes gateway install --systemz+  Or run in foreground:  hermes gateway runNr÷   F)ÚforceÚenable_on_startuprø   )r  Ú	start_now)r  r  Ústart_on_loginrÿ   úStart failedrè   )rß   rè   z  Install failed: z.  You can try manually: hermes gateway installz+  Gateway service install did not complete.)r	   Úis_wslri   Ú_WIZARD_BACKEND_LABELSr‹   rá   Ú install_linux_gateway_from_setupÚlaunchd_installÚ_gw_windowsÚinstallrX   rä   rô   rõ   rñ   Ú
SystemExitrŠ   )rö   Úwsl_noter  r  Úinstalled_scopeÚdid_installr8   s   &      r   Ú_wizard_install_servicer#  Ä  s×  € ô DGÃ5Ç<Á<Ç>Â>Ñ?ÐWY€HÜ“×#Ñ#Ð$>ÀÓE€IÜ“U×(Ñ(Ø
?Ô@VÐW^Õ@_Ð?`Ð`iØˆ*ð	àó€N÷
 ŸÜ‹×ÑÐ@ÔAÜ‹×ÑÐJÔKÜ‹5×*Ñ*×,Ò,Ü‹E×ÑÐ`ÔaÜ‹×ÑÐFÔGÙðKØ'+¨T˜Ø�iÔÜ+.«5×+QÑ+QØ¨~ð ,Ró ,Ñ(ˆO˜[ð ˜	Ô!Ü‹E×!Ñ!¨¸Ð!ÕCä‹E×ÑÓ×'Ñ'¨e¸yÐ'ÔhÙÜŒßŸ9Ü‹E×'Ñ'¨¸nÐUdÐhpÑUpÐ'Öqñ %‰;øä×(Ñ(ô KÜ‹×ÑÐ.¨q¨cÐ2Ô3Ü‹×ÑÐI×JÒJûÜô Kô 	‹×ÑÐIÔJÜ‹×ÑÐI×Jð	Kús1   Ã=A4F2 Å3F2 ÆF2 Æ2IÇ5HÈIÈ3IÉIc               ó   € V ^8„  d   QhRR/# rý   r    )r!   s   "r   r"   r"   ò  s   € ÷ hñ h˜Dñ hr
   c                 ó"  a€ \        4        \        \        4       P                  R\        4       P                  P                  4      4       \        4       P                  4       '       d   R# \        4       P                  4       p \        4       P                  4       pV'       d   \        RRR4       R# V '       d   \        RRR4       R# \        4        \        4       P                  4       pVe   \        4       P                  V4       R# \        4       P                  4       '       d   RR	upoM4\        4       P                  4       '       d   ^ R
IHp RV! 4       upoMRR	upo\        4       P                  ! V3R l\         V,           4       !   R# )zSOffer to install/start/restart the gateway once at least one platform has progress.Nrì   z)  Restart the gateway to pick up changes?zRestart failedrÿ   z  Start the gateway service?r  rù   r(   )Údisplay_hermes_homerú   rû   c              3  óF   <"  € T F  qP                  SR 7      x € K  	  R# 5i))ÚhomeN)r!   )rb   r½   r(  s   & €r   rd   Ú%_wizard_post_setup.<locals>.<genexpr>  s   øé € Ð!fÑEe¸T§+¡+°4 +×"8Ð"8ÓEeùs   ƒ!u®   â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€)rX   r	   rY   rZ   ÚDIMÚ _served_profile_needs_no_servicer   r  ræ   rí   r#  r  Ú	is_termuxÚhermes_constantsr&  r–   Ú_WIZARD_NO_SERVICE_LINES)r  r  rö   ÚreasonÚ_dhhr(  s        @r   Ú_wizard_post_setupr1  ò  s  ø€ ä	„GÜ	Œ#‹%�+‰+�j¤#£%§,¡,×"2Ñ"2Ó
3Ô4Ü
ƒu×-Ñ-×/Ò/ÙÜ›×3Ñ3Ó5ÐÜ“e×/Ñ/Ó1€OçÜ$ YÐ0[Ð]mÖnß	Ü$ WÐ.LÈnÖ]äŒÜ“%×(Ñ(Ó*ˆØÒÜ‹E×)Ñ)¨'Ô2ÙÜ‹5�<‰<�>Š>Ø  "ˆLˆF‘DÜ‹U�_‰_×ÒÝDØ#¡T£VˆLˆF‘Dà(¨"ˆLˆF�DÜ‹×ÒÔ!fÔE]Ð^dÖEeÓ!fÔgr
   c                 ó¾  a€ \        4       P                  4       '       d   \        4       P                  R4       R# \        4        \         FB  p \        \        4       P                  V \        4       P                  P                  4      4       KD  	  \        4        \        4        R R lo\        ;QJ d5    V3R l\        4       P                  4        4       F  '       g   K   RM*	  RM&! V3R l\        4       P                  4        4       4      '       d   \        4       P                  4        M#\        4        \        4       P                  R4       \        4        R# )	z<Interactive setup for messaging platforms + gateway service.zrun gateway setupNc               ó    € V ^8„  d   QhRRRR/# )r   Ústatusr@   r   rH   r    )r!   s   "r   r"   Ú#gateway_setup.<locals>.__annotate__  s   € ÷ kñ k˜Sð k Tñ kr
   c                óš   € V P                  4       pVR 8H  ;'       g+    VP                  R4      ;'       g    VP                  R4      '       * # )rE   Ú	partiallyzplugin disabled)r©   r¥   )r4  Úss   & r   Ú_is_progressÚ#gateway_setup.<locals>._is_progress  s?   € Ø�L‰L‹NˆØÐ)Ñ)×iÐi¨Q¯\©\¸+Ó-F×iÐiÈ!Ï,É,ÐWhÓJiÔjÐjr
   c              3  ób   <"  € T F$  pS! \        4       P                  V4      4      x € K&  	  R # 5ira   )r	   rK   )rb   r:   r9  s   & €r   rd   Ú gateway_setup.<locals>.<genexpr>!  s(   øé € Ð
SÑ<R°q‰<œ›×.Ñ.¨qÓ1×2Ð2Ó<Rùs   ƒ,/TFz?No platforms configured. Run 'hermes gateway setup' when ready.)r	   Ú
is_managedÚmanaged_errorrX   Ú_WIZARD_BANNERrY   rZ   ÚMAGENTAr  r  Úanyr>   r1  r‹   )Úbanner_liner9  s    @r   Úgateway_setuprC    sÎ   ø€ ä
ƒu×Ñ×ÒÜ‹×ÑÐ/Ô0Ùä	„Gß%ˆÜŒc‹e�k‰k˜+¤s£u§|¡|×';Ñ';Ó<Ö=ñ &ô !Ô"ÜÔõk÷ ƒsÔ
S¼C»E×<PÑ<PÔ<RÓ
S‡s‡s‚sÔ
S¼C»E×<PÑ<PÔ<RÓ
S×SÒSÜ‹× Ñ Õ"äŒÜ‹×ÑÐZÔ[ä	†Gr
   )uC   1. In Mattermost: Integrations â†’ Bot Accounts â†’ Add Bot AccountuE      (System Console â†’ Integrations â†’ Bot Accounts must be enabled)z:2. Give it a username (e.g. hermes) and copy the bot tokenuK   3. Works with any self-hosted Mattermost instance â€” enter your server URLuA   4. To find your user ID: click your avatar (top-left) â†’ Profileu8      Your user ID is displayed there â€” click it to copy.uI      âš  This is NOT your username â€” it's a 26-character alphanumeric ID.uL   5. To get a channel ID: click the channel name â†’ View Info â†’ copy the ID)é   z9Enable open access (any email sender can message the bot)z=Use DM pairing (unknown email senders receive a pairing code)úAPolitely decline unknown senders (one-time message, then silence)zKeep unknown senders silent)é   z/Enable open access (anyone can message the bot)zXUse DM pairing (unknown users request access, you approve with 'hermes pairing approve')rE  z7Skip for now (bot will deny all users until configured))u±   â”Œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”�u@   â”‚             â˜¤ Gateway Setup                            â”‚u±   â”œâ”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”¤u?   â”‚  Configure messaging platforms and the gateway service. â”‚u>   â”‚  Press Ctrl+C at any time to exit.                     â”‚u±   â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜)z*  WSL detected but systemd is not running.ú'  Run in foreground: hermes gateway runz<  For persistence:   tmux new -s hermes 'hermes gateway run'zM  To enable systemd: add systemd=true to /etc/wsl.conf, then 'wsl --shutdown')z/  Termux does not use systemd/launchd services.rG  zp  Or start it manually in the background (best effort): nohup hermes gateway run >{home}/logs/gateway.log 2>&1 &)z1  Service install not supported on this platform.rG  )"Ú__doc__Ú
__future__r   Úshutilrô   r/   r	   r1   r>   rK   rT   r\   rj   rq   rw   r   rˆ   r�   r�   r­   r¸   rÍ   rÕ   rÛ   ræ   rä   r?  r  r.  r  r  r#  r1  rC  r    r
   r   Ú<module>rK     sÉ  ðñõ #ã Û Û 
òð 	ˆ|˜W l°G¸VÀ[ÐRdØò 	
ð 	ØÐ% xÐ1[Ø˜ Ð(jðlàÐ'¨°;À
ÈDØÐ=ð?àÐ/°Ð;_Ø˜ °°fÐ>jðlàÐ.ØÐoØ˜ Ð(jðlð Ð,ØÐmØ˜ØÐ]ð_ð
ðð€
õ@õ>Põ,dõ
Rõ
õ@õ*õ
Oð 	ð 'ð
 
ð Cð Ð õVõ.õ8õõB>8õBõ:õ2Qð4Ø7;ð4ØLQ÷4ð.€ð $ Y°	¸9ÀiÐQaÐbÐ ð
 
ð ð
 ð ð ð ðÐ õ Yõ0
5õ+Kõ\hô:r
   