+
    „WÝj­³  ã                  ó€  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
Ht ^ RIHt ^ RIHtHtHt ^ RIHt ^ RIHt ]P,                  ! ]4      t]! R	RR
7      tR]R&   ]	R 4       tR R ltR t ! R R]4      tRR/R R llt RR/R R llt!R R lt"R R lt#RR/R R ll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, R- lt+R. R/ lt,R0RR1RR2RR3RR4R5R6RR7RR8RR9R/	R: R; llt-R< R= lt.R> R? lt/R@ RA lt0RRRB RC llt1RD RE lt2RF RG lt3RH RI lt4RJ RK lt5RL RM lt6RNRR1RR6RROR/RP RQ llt7R# )Sa!  ``hermes plugins install``: dependency/env consent, the atomic clone-scan-publish installer core, and
the dashboard/TUI non-interactive install.

Sibling of :mod:`hermes_cli.plugins_cmd` (the facade re-exports the names other modules use and is
imported late here, never at module level).
)ÚannotationsN)Úcontextmanager)Ú
ContextVar©ÚPath)ÚAnyÚCallableÚOptional)Ú
line_input)ÚInstallPhaseÚplugin_dependency_answers)ÚdefaultzContextVar[Optional[dict]]Ú_shared_answersc               #  ó    "  € \         P                  / 4      p  Rx € \         P                  V 4       R#   \         P                  T 4       i ; i5i)zYInside this block each dependency question is asked once; repeats reuse the first answer.N)r   ÚsetÚreset)Útokens    ÚRC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\plugins_cmd_install.pyÚshared_dependency_answersr      s;   é € ô ×Ñ Ó#€Eð%Ûä×Ñ˜eÖ$øŒ×Ñ˜eÕ$üs   ‚A™4 �A´AÁAc               ó$   € V ^8„  d   QhRRRRRR/# )é   ÚkeyÚtupleÚpromptÚstrÚreturnÚbool© )Úformats   "r   Ú__annotate__r   '   s!   € ÷ ñ �Uð  Cð °Tñ ó    c                ó4  € \         P                  4       pVe4   W9   d.   TP                  RW0,          '       d   RMR R24       W0,          #  \        V4      P	                  4       P                  4       R9   pVe   WCV &   V#   \        \        3 d    Rp Li ; i)Nz2  [dim]Reusing your answer for the first profile: ÚyesÚnoú[/dim]F>   Úyr"   )r   ÚgetÚprintÚinputÚstripÚlowerÚEOFErrorÚKeyboardInterrupt)r   r   ÚconsoleÚanswersÚaccepteds   &&&  r   Ú_ask_yes_nor0   '   s›   € Ü×!Ñ!Ó#€GØÒ˜sœ~Ø�‰ÐJÐT[×T`ÔT`É5ÐfjÐJkÐkqÐrÔsØ�|ÐðÜ˜“=×&Ñ&Ó(×.Ñ.Ó0°LÑ@ˆð ÒØ�‰Ø€Oøô	 Ô'Ð(ô ØŠðús   Á*B ÂBÂBc                 ó   € ^ RI Hp  V # )z`The facade, read at call time: tests patch ``plugins_cmd.<name>`` and sibling calls must see it.©Úplugins_cmd)Ú
hermes_clir3   r2   s    r   Ú_pcr5   5   s   € å&ØÐr    c                  ó2   a € ] tR t^;tRtR V 3R lltRtV ;t# )Ú_ConsentRefusalz�A refusal reason (user-facing text) carrying its closed extension-install ``failure_class``,
so publication classifies the refusal without matching the copy.c               ó$   € V ^8„  d   QhRRRRRR/# )r   Útextr   Úfailure_classr   r7   r   )r   s   "r   r   Ú_ConsentRefusal.__annotate__?   s!   € ÷ ñ ˜3ð ¨sð °ñ r    c                	ó2   <€ \         SV `  W4      pW#n        V# ©N)ÚsuperÚ__new__r:   )Úclsr9   r:   ÚrefusalÚ	__class__s   &&& €r   r?   Ú_ConsentRefusal.__new__?   s   ø€ Ü‘'‘/ #Ó,ˆØ -ÔØˆr    r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r?   Ú__static_attributes__Ú__classcell__)rB   s   @r   r7   r7   ;   s   ø† ñH÷ö r    r7   Ú
assume_yesFc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   ÚmanifestÚdictÚtargetr   rK   r   r   útuple[bool, Optional[str]]r   )r   s   "r   r   r   E   s2   € ÷ 0kñ 0kØð0kØ ð0kØ:>ð0kàñ0kr    c               ó  € ^ RI Hp  V! V4      pVP                  pTP
                  pTR,          P                  4       p	T'       g   T	'       g   R# Rp
T	'       dÖ   TP                  RT P                  R	R
4       R24       \        P                  P                  4       ;'       dE    \        P                  P                  4       ;'       d    \        RT P                  R	4      3RT4      pT'       d.   ^ RIHp T! TRR7      p
T
'       d   TP                  RT
 24       MTP                  R4       T'       g   R# \!        T P                  R	R
4      YbTR7      #   \         d   pR\	        RT 2R4      3u Rp?# Rp?ii ; i)u  Consent gate for plugin python deps (settled 2026-09-02; C13 rework).

Node sidecar: y/n prompt â†’ ``npm ci`` into the plugin's OWN
node_modules (separate question, failure never blocks enable).
Python deps: NO resolution here â€” the resolve runs inside the ONE
admission transaction when the enable commits
(:func:`_admit_and_save_plugin_sets`), so the environment and the
config always change together or not at all. Returns (consented,
reason): consented=True when the user accepted (or no prompt was
needed); a decline/skip returns False and NOTHING is installed.
Never raises â€” the caller keeps the plugin installed-but-disabled.
*assume_yes* is ``--yes-deps``: the user's own non-interactive answer
to the Python question, so a headless install is not refused (#122134).
©Úread_python_declarationFz'invalid Python dependency declaration: Úmanifest_invalidNzpackage.jsonTú
[bold]Únameúthis pluginz2[/bold] declares Node dependencies (package.json).Únodez>  Install them into the plugin's own node_modules now? [y/N]: )Úinstall_node_sidecar)Úexplicitu    [yellow]âš [/yellow] Node deps: uN   [dim]Skipped Node deps â€” run `hermes plugins install` again to retry.[/dim]
©rK   ©TN)Úpm.plugin_declarationsrS   Úinstall_requirementsÚ	Exceptionr7   Úinstalls_packagesÚis_filer'   r&   ÚsysÚstdinÚisattyÚstdoutr0   Úpm.workspacerY   Ú_consent_python_deps)rM   rO   r-   rK   rS   ÚdeclarationÚdepsÚexcÚ
has_pythonÚhas_package_jsonÚnode_reasonÚnode_okrY   s   &&&$         r   Ú_install_plugin_python_depsro   E   s_  € õ" ?ðkÙ-¨fÓ5ˆØ×/Ñ/ˆð ×.Ñ.€JØ Õ/×8Ñ8Ó:Ðß×.ØÐð
 €KßØ�‰˜ §¡¨f°mÓ!DÐ EÐEwÐxÔyÜ—)‘)×"Ñ"Ó$÷ wð w¬¯©×):Ñ):Ó)<÷ wð wÄØ�X—\‘\ &Ó)Ð*Ð,lÐnuóBwˆçÝ9á.¨vÀÔEˆKßØ—‘Ð @ÀÀÐNÔOøà�M‰MÐkÔlçØÐÜ §¡¨V°]Ó CÀTÐ_iÔjÐjøô5 ô kØ”oÐ(OÐPSÈuÐ&UÐWiÓjÐjÕjûðkús   ˆE ÅE>Å#E9Å3E>Å9E>c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úplugin_namer   ri   ztuple[str, ...]rK   r   r   rP   r   )r   s   "r   r   r   x   s,   € ÷ )ñ )Øð)Ø+ð)ØEIð)àñ)r    c               ó
  € VP                  RV  R24       V'       d   V F  pVP                  RV 24       K  	  MVP                  R4       V'       d   VP                  R4       R# \        P                  P                  4       '       d%   \        P                  P                  4       '       g    VP                  R4       R\        RR	4      3# \        R
W3RV4      '       g    VP                  R4       R\        RR4      3# R# )u\  The y/N gate for Python deps entering the shared environment â€” install,
reinstall AND an update that declares new ones all pass through here.
Returns (consented, reason); never raises. *assume_yes* (``--yes-deps``)
answers the question on the user's behalf ONLY because the user passed the
flag; the non-interactive default below stays a refusal.rU   z%[/bold] declares Python dependencies:z  - z$  - (declared in its pyproject.toml)uH   [dim]Consent given up front â€” preparing them without prompting.[/dim]
u|   [dim]Non-interactive install â€” skipping dependency install. Run `hermes plugins enable` when ready to prepare them.[/dim]
Fz,dependency install skipped (non-interactive)Únon_interactiveÚpythonz3  Prepare these with Hermes through PM now? [y/N]: uO   [dim]Skipped â€” run `hermes plugins enable` when ready to prepare them.[/dim]
zdependency install declinedÚdeps_declinedr\   )r'   rb   rc   rd   re   r7   r0   )rq   ri   r-   rK   Údeps   &&&$ r   rg   rg   x   sü   € ð ‡M�MØ
�;�-ÐDÐEô÷ ÛˆCØ�M‰M˜D  ˜,Ö'ò ð 	�‰Ð<Ô=÷ Ø�‰ØWô	
ð Ðô �I‰I×Ñ×Ò¤3§:¡:×#4Ñ#4×#6Ò#6Ø�‰ðNô	
ð ”oÐ&TÐVgÓhÐhÐhÜ˜ +Ð4Ð6kÐmt×uÒuØ�‰ð'ô	
ð ”oÐ&CÀ_ÓUÐUÐUð
 Ðr    c               ó$   € V ^8„  d   QhRRRRRR/# )r   rO   r   Úwarningsú	list[str]r   r   )r   s   "r   r   r   ¤   s!   € ÷ ñ  tð °yð ÀYñ r    c                ó¢   € ^ RI Hp  \        V! V 4      P                  4      #   \         d!   pTP                  RT 24       . u Rp?# Rp?ii ; i)zNRead dashboard dependency details; publication and admission own installation.rR   z$Could not read Python dependencies: N)r]   rS   Úlistr^   r_   Úappend)rO   rx   rS   rj   s   &&  r   Ú_python_dependency_summaryr}   ¤   sJ   € å>ðÜÑ+¨FÓ3×HÑHÓIÐIøÜô Ø�‰Ð>¸s¸eÐDÔEØ�	ûðús   ˆ# £A®A	ÁAÁ	Ac               ó    € V ^8„  d   QhRRRR/# )r   rM   rN   r   ÚNoner   )r   s   "r   r   r   ¯   s   € ÷ ñ  dð ¸ñ r    c                ó‚  € \        4       P                  V 4      pV'       g   R# ^ RIHp ^ RIHp V P                  RR4      pVP                  RV R24       V EF  pVR,          pVP                  RR	4      pVP                  R
R	4      p	TP                  RV 2V'       d   RV 2MR	,           4       V	'       d   VP                  RV	 R24        VP                  RR4      '       d   \        4       P                  M\        ! RV R24      P                  4       p
T
'       d9   T! Yz4       T
\        P                  T&   TP                  RT! 4        R24       EK  TP                  RT RT! 4        R24       EK!  	  VP                  4        R#   \        \        3 d     TP                  RT! 4        R24         R# i ; i)zXPrompt for unset ``requires_env`` variables and save the answers to the user's ``.env``.N)Úsave_env_value)Údisplay_hermes_homerV   rW   rU   z6[/bold] requires the following environment variables:
ÚdescriptionÚ Úurlú  u    â€” z  [dim]Get yours at: r$   ÚsecretFú: z,
[dim]  Skipped (you can set these later in z/.env)[/dim]u     [green]âœ“[/green] Saved to z/.envz  [dim]  Skipped (set z in z/.env later)[/dim])r5   Ú_missing_env_specsÚhermes_cli.configr�   Úhermes_constantsr‚   r&   r'   Úmasked_secret_promptr
   r)   r+   r,   ÚosÚenviron)rM   r-   Úmissingr�   r‚   rq   ÚspecrV   Údescr…   Úvalues   &&         r   Ú_prompt_plugin_env_varsr“   ¯   s�  € ä‹e×&Ñ& xÓ0€GßÙÝ0Ý4Ø—,‘,˜v }Ó5€KØ‡M�M�H˜[˜MÐ)`ÐaÔbÜˆØ�F�|ˆØ�x‰x˜ rÓ*ˆØ�h‰h�u˜bÓ!ˆØ�‰˜˜4˜&�k·t u¨T¨F¡^ÀÕDÔEßØ�M‰MÐ1°#°°fÐ=Ô>ð	Ø37·8±8¸HÀe×3LÒ3L”S“U×/Ò/ÔR\Ð\Ð`bÐcgÐbhÐhjÐ^kÓl×rÑrÓtˆE÷
 Ù˜4Ô'Ø$ŒB�J‰J�tÑØ�M‰MÐ:Ñ;NÓ;PÐ:QÐQVÐW×Xà�M‰MÐ2°4°&¸Ñ=PÓ=RÐ<SÐSeÐf×gñ% ð( ‡M�M†Oøô Ô+Ð,ô 	Ø�M‰MÐIÑJ]ÓJ_ÐI`Ð`lÐmÔnÛð	ús   ÃFÃ(2FÆ+F>Æ=F>Úbriefc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Ú
plugin_dirr   Ú
identifierr   r”   r   r   r   r   )r   s   "r   r   r   Ï   s)   € ÷ ñ  tð ¸ð Èð ÐY]ñ r    c          	     óŠ  € ^ RI Hp ^ RIHp \	        4       P                  4       pV R,          pV'       d   VP                  4       '       g   R# VP                  4       '       d   V! VP                  RR7      4      Rr‡M
RV RV  2pR	pVP                  4        VP                  V! VR
VRR7      4       VP                  4        R# )zWShow after-install.md if it exists, otherwise a default message (skipped when *brief*).)ÚMarkdown)ÚPanelúafter-install.mdNz	utf-8-sig)Úencodingz![green bold]Plugin installed:[/] z
[dim]Location:[/] u   âœ“ InstalledÚgreenF)Úborder_styleÚtitleÚexpand)	Úrich.markdownr™   Ú
rich.panelrš   r5   Ú_consoleÚexistsÚ	read_textr'   )	r–   r—   r”   r™   rš   r-   Úafter_installÚbodyrŸ   s	   &&$      r   Ú_display_after_installr¨   Ï   s¡   € å&Ý Ü‹e�n‰nÓ€GØÐ!3Õ3€Mß�]×)Ñ)×+Ò+ÙØ×Ñ×ÒÙ˜}×6Ñ6ÀÐ6ÓLÓMÈt‰eà2°:°,Ð>RÐS]ÐR^Ð_ˆØˆØ‡M�M„OØ‡M�M‘%˜¨7¸%ÈÔNÔOØ‡M�M†Or    c               ó$   € V ^8„  d   QhRRRRRR/# )r   rM   rN   rq   r   r   r   r   )r   s   "r   r   r   á   s&   € ÷ Gñ G dð G¸ð GÀñ Gr    c                óŠ   € ^ RI Hp V! W4      pV'       d-   ^ RIHp \	        4       P                  V RV! 4        R2RR7      hR# )zUReject manifests declaring a newer ``manifest_version`` than this installer supports.)Úmanifest_version_error)Úrecommended_update_commandz Run z to update Hermes.Úincompatible©r:   N)r]   r«   rŠ   r¬   r5   ÚPluginOperationError)rM   rq   r«   Úreasonr¬   s   &&   r   Ú_check_manifest_versionr±   á   sN   € å=á# HÓ:€FßÝ@Ü‹e×(Ñ(¨F¨8°5Ñ9SÓ9UÐ8VÐVhÐ)iØ7Eð )ó Gð 	Gñ r    c               ó    € V ^8„  d   QhRRRR/# )r   r–   r   r   rN   r   )r   s   "r   r   r   ì   s   € ÷ ñ ¨4ð °Dñ r    c                ód  € \        4       P                  V 4      pVeQ    \        4       P                  V4      p\        T\        4      '       g   \        4       P	                  RT 2RR7      hT# \        4       P                  V 4      '       g   / #  ^ RIH	p V! V 4      w  r%T F#  p\        P                  R	TP                  4       K%  	  T#   \         d(   p\        4       P	                  RT RT 2RR7      ThRp?ii ; i  \         d%   p\        4       P	                  RT 2RR7      ThRp?ii ; i)
zEA candidate's unreadable or malformed manifest must stop publication.NzCould not read plugin manifest rˆ   rT   r®   z#Plugin manifest must be a mapping: )Úread_agent_plugin_manifestz,Portable plugin manifest validation failed: zAgent Plugin install: %s)r5   Ú_native_manifest_fileÚ_load_yaml_manifestr_   r¯   Ú
isinstancerN   Ú_has_portable_manifestÚhermes_cli.agent_pluginsr´   ÚloggerÚwarningÚmessage)r–   ÚnativerM   rj   r´   ÚdiagnosticsÚ
diagnostics   &      r   Ú_read_manifest_for_installrÀ   ì   sO  € ä‹U×(Ñ(¨Ó4€FØÒð	XÜ“u×0Ñ0°Ó8ˆHô ˜(¤D×)Ò)Ü“%×,Ñ,Ð/RÐSYÐRZÐ-[Ø;Mð -ó Oð OàˆÜ‹5×'Ñ'¨
×3Ò3Øˆ	ðTÝGÙ :¸:Ó FÑˆó "ˆ
Ü�‰Ð1°:×3EÑ3EÖFñ "à€Oøô# ô 	XÜ“%×,Ñ,Ð/NÈvÈhÐVXÐY\ÐX]Ð-^Ø;Mð -ó OØTWðXûð	Xûô ô TÜ‹e×(Ñ(Ð+WÐX[ÐW\Ð)]Ø7Ið )ó KØPSð	TûðTús/   ŸC ÂD  ÃC=Ã"C8Ã8C=Ä D/ÄD*Ä*D/c               ó    € V ^8„  d   QhRRRR/# )r   Úpathr   r   r   r   )r   s   "r   r   r     s   € ÷ ñ ˜$ð  4ñ r    c                óÆ   € V P                  4       '       d   \        P                  ! V 4       R# \        V R4      ;_uu_ 4         RRR4       R#   + '       g   i     R# ; i)zZRaise ``OSError`` unless *path* can actually be listed (dir) or opened for reading (file).ÚrbN)Úis_dirr�   ÚlistdirÚopen)rÂ   s   &r   Ú_probe_readablerÈ     s8   € à‡{�{‡}‚}Ü
�
Š
�4Öä�$˜×ÕØ÷ ××Òús   ÁAÁA 	c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úrootr   Úplugins_dirr   r   r   )r   s   "r   r   r     s!   € ÷ ñ  ð °4ð ¸Dñ r    c                óî  a€ V .p\         P                  ! V 4       F%  w  or4VP                  V3R l. VOVO 4       4       K'  	  V F  p \        V4       K  	  R#   \         d‚    \         P
                  R8w  dj    \         P                  ! T\         P                  ! T4      P                  TP                  4       '       d   RMR,          4        M  \         d      M
i ; i Mi ; i \        T4       K²    \         dr   p\         P
                  R8X  d   RT R2MRT 2p\        4       P                  RTP                  T 4       R	TP                  ;'       g    T R
T RT R2	RR7      ThRp?ii ; i)a  Refuse to ship a tree Hermes cannot read back. A clone can land unreadable (Windows ACL
inheritance -> WinError 5, a mode-000 file) and discovery would then skip the plugin forever
(#111804); repair ``u+rX`` where the OS supports it, otherwise fail before anything moves.c              3  óH   <"  € T F  p\        S4      V,          x € K  	  R # 5ir=   r   )Ú.0rV   Údirpaths   & €r   Ú	<genexpr>Ú(_ensure_tree_readable.<locals>.<genexpr>  s   øé € ÐNÑ6M¨d”T˜'“] T×)Ò)Ó6Mùs   ƒ"Únti@  é   zicacls "z$" /grant:r "%USERNAME%":(OI)(CI)F /Tzchmod -R u+rX zInstalled file z is not readable (z-); nothing was installed. Fix permissions on z (e.g. `z`) and retry.Ú
permissionr®   N)r�   ÚwalkÚextendrÈ   ÚOSErrorrV   ÚchmodÚstatÚst_moderÅ   r5   r¯   Úrelative_toÚstrerror)	rÊ   rË   ÚpathsÚdirnamesÚ	filenamesrÂ   rj   ÚfixrÏ   s	   &&      @r   Ú_ensure_tree_readablerá     sm  ø€ ð ˆF€EÜ(*¯ª°®Ñ$ˆ�Ø�‰ÔNÐ6M¸Ð6MÀ9Ñ6MÓNÖNñ )6ãˆð	Ü˜DÔ!Ùó øô ô 	Ü�w‰w˜$ŒðÜ—H’H˜T¤2§7¢7¨4£=×#8Ñ#8ÀTÇ[Á[Ç]Â]¹EÐX]Õ#^Ö_øÜô Úðúñ ð	úð		Ü˜DÖ!øÜô 	ÜSU×SZÑSZÐ^bÔSb�X˜k˜]Ð*NÑOØ(¨¨Ð6ð ä“%×,Ñ,Ø! $×"2Ñ"2°4Ó"8Ð!9Ð9KÈCÏLÉL×L_ÐL_Ð\_ÐK`ð a=Ø=H¸MÈÐRUÐQVÐVcðeà*ð -ó ð ð	ûð	úsV   Á
AÁ C'Á<ACÃCÃC!ÃC'Ã C!Ã!C'Ã&C'Ã+C8Ã8E4ÄAE/ÅE/Å/E4c               ó$   € V ^8„  d   QhRRRRRR/# )r   rq   r   Útreer   r   r   r   )r   s   "r   r   r   ,  s!   € ÷ 
ñ 
°Sð 
Àð 
Èñ 
r    c                óž  € VR ,          P                  4       '       g   R# ^ RIHp ^ RIHp ^ RIHp  V! WP                  R,          4      pTP                  P                  4        F­  w  rxT! TP                  4      p	T	P                  '       d   K+  T	P                  '       d   RT	P                   2MRp
T	P                   R8X  d    RT! TP                  P"                  4       2p
\        4       P                  RT  RT RT	P                    T
 R2RR
7      h	  R#   \         d)   p\        4       P                  RT  RT R2R	R
7      ThRp?ii ; i)zplugin.jsonN)Úload_agent_plugin)Ú	gpu_label)Úavailabilityz.hermes-install-dataúPlugin 'z' is unavailable: Ú.rT   r®   z, found version r„   Úunsupported_gpuz, needs z
' server 'r­   )ra   r¹   rå   Úhermes_platform.declarationræ   Ú%hermes_platform.resolver.availabilityrç   ÚparentÚ
ValueErrorr5   r¯   Úserver_declarationsÚitemsrh   Ú	offerableÚversionÚstateÚrequired_gpu)rq   rã   rå   ræ   rç   Úpackagerj   Úserver_nameÚserver_declÚresultÚfounds   &&         r   Ú#_refuse_unavailable_portable_pluginrú   ,  sM  € Ø�=Õ ×)Ñ)×+Ò+ÙÝ:Ý5ÝBðTÙ# D¯+©+Ð8NÕ*NÓOˆð %,×$?Ñ$?×$EÑ$EÖ$GÑ ˆÙ˜k×5Ñ5Ó6ˆØ××ÐÙØ7=·~·~°~Ð" 6§>¡>Ð"2Ñ3È2ˆØ�<‰<Ð,Ô,Ø™y¨×)@Ñ)@×)MÑ)MÓNÐOÐPˆEÜ‹e×(Ñ(Ø�{�m :¨k¨]Ð:LÈVÏ\É\ÈNÐ[`ÐZaÐabÐcØ(ð )ó 
ð 	
ó %Høô ô TÜ‹e×(Ñ(¨8°K°=Ð@RÐSVÐRWÐWXÐ)YØ7Ið )ó KØPSð	TûðTús   ³D ÄEÄ$#EÅEc               ó   € V ^8„  d   QhRR/# )r   r   ry   r   )r   s   "r   r   r   E  s   € ÷ Eñ E Iñ Er    c                óJ   € V P                    Uu. uF  pRV 2NK
  	  up# u upi )z½Catalog ``known_issues`` are informational (#124058): surface them as warnings, never a gate.

The guard for the traps they describe belongs at the mode-selection seam (#122341 / #123771).
zKnown issue: )Úknown_issues)ÚentryÚissues   & r   Ú_known_issue_warningsr   E  s+   € ð
 27×1CÒ1CÓDÑ1C¨ˆm˜E˜7Ó#Ñ1CÑDÐDùÒDs   � c               ó    € V ^8„  d   QhRRRR/# )r   Úverbr   r   zCallable[[Any], bool]r   )r   s   "r   r   r   M  s   € ÷ ñ ¨Sð Ð5Jñ r    c                ó   a a€ R V V3R llpV# )z]The terminal ``[y/N]`` that accepts a caution verdict, shared by install and update (*verb*).c               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   Ú/interactive_scan_decision.<locals>.__annotate__O  s   € ÷ vñ v˜tñ vr    c                óú   <€ ^ RI Hp SP                  4        SP                  R4       SP                  V! V 4      4       \        4       P	                  4       ;'       d    \        4       P                  RS R24      # )é    )Úformat_scan_reportu7   [yellow]âš  Security scan flagged this plugin:[/yellow]r†   z7 anyway? Only continue if you trust the source. [y/N]: )Útools.plugin_guardr  r'   r5   Ú_is_ttyÚ_ask_yes)Úscan_resultr  r-   r  s   & €€r   ÚdecideÚ)interactive_scan_decision.<locals>.decideO  sY   ø€ Ý9Ø�‰ŒØ�‰ÐOÔPØ�‰Ñ(¨Ó5Ô6Ü‹u�}‰}‹×uÐu¤3£5§>¡>°B°t°fÐ<sÐ2tÓ#uÐur    r   )r-   r  r  s   ff r   Úinteractive_scan_decisionr  M  s   ù€ ÷vñ vð €Mr    c               ó   € V ^8„  d   QhRR/# )r   r   údict[str, Any]r   )r   s   "r   r   r   X  s   € ÷ ñ  ñ r    c                ó  € R
pRRR\        V 4      RRR\        V P                  RR4      R	V P                  e   V P                  P                  MR UUu. uF  pV Uu/ uF  q3\        W#4      bK  	  upNK   	  upp/# u upi u uppi )z�The non-interactive surfaces' answer to a scan block: the verdict and findings, so the client can
show them and, for a caution verdict, retry with ``force``.ÚokFÚerrorÚscan_blockedTÚscan_verdictÚverdictÚ	dangerousÚscan_findings)Ú
pattern_idÚseverityÚcategoryÚfileÚlinerƒ   r   )r   Úgetattrr  Úfindings)rj   ÚfieldsÚfÚks   &   r   Úscan_blocked_resultr$  X  sŽ   € ð S€Fàˆe�Wœc #›h¨¸Øœ §¡°¸KÓHØà25·/±/Ò2M�c—o‘o×.Ò.ÐSUÐUô
áU�ñ (.Ó.¡v !”˜“Ò¡vÔ.ÙUò
ðð ùò /ùó
s   Á	BÁA<Á0BÁ<BÚaccept_cautionÚrefÚscan_decision_cbÚreviewed_pinÚpython_depsTÚassume_deps_consentÚcatalogÚallow_removedÚbefore_swapc               ó@   € V ^8„  d   QhRRRRRRRRR	RR
RRRRRRRRR/
# )r   r—   r   Úforcer   r%  úOptional[bool]r&  úOptional[str]r(  r)  r*  r+  úOptional[dict]r,  r   ztuple[Path, dict, str]r   )r   s   "r   r   r   f  s†   € ÷ cUñ cUØðcUð ðcUð #ð	cUð
 
ðcUð  ðcUð ðcUð ðcUð ðcUð ðcUð ñcUr    c       
        óÚ  a.a/a0€ Ve   \        4       P                  V4      MRp \        4       P                  V 4      w  rÍ\        4       P                  4       p\        4       P                  YÍ4      p\        4       P                  4       pTf±   TP                  4        Uu. uF3  qîP                  R4      T8X  g   K  TP                  R4      RJ g   K1  TNK5  	  pp\        T4      ^8X  dT   \        T^ ,          P                  R4      \
        4      '       d(   \        4       P                  T^ ,          R,          4      p\        P                  ! RTR	7      ;_uu_ 4       p\        T4      R
,          p\        4       P!                  TYËT4      p\        4       P#                  4       p\%        T4      ;'       d1    TT'       d$   T'       d   \        4       P'                  TTT4      MT8H  pT'       d   \        4       P)                  TT4      MTp\+        TT4       \-        T4      pTP                  R4      ;'       gJ    T'       d)   TP/                  R4      P1                  R^4      R5,          M\        4       P3                  T4      pT\        T4      ,          p^ RIHp R\        T4      9  dg   TP9                  4       '       g   T! T4      '       dC   \        4       P	                  RT RT R\:        P<                  P?                  T4       R2RR7      h \        4       PA                  TT4      o0\C        TT4       TP                  T4      p. pT
f~   T'       dv   S0PE                  4       '       d`   S0P9                  4       '       gJ   \        T\F        4      '       d4   TP                  R4      T8X  d   ^ RI$H%o.H&p T! S04      w  o/pT.T/T03R lp T p
T
e
   T
! TT4      MRp!\        4       PO                  TT T!Tf   TMTTTR7       T'       g>   ^ RI(H)p" S0PU                  4       T"! S0R7      9   d   \        4       P	                  RRR7      h\W        TT4       S0PY                  4       '       dE   T'       g=   ^ RI-H.p# ^ RI/H0p$ \        4       P	                  RT RT#! T$! 4       4       RT R2RR7      hS0PY                  4       '       dO   TfK   \        T\F        4      '       d5   TP                  R4      RJ d    \        4       P	                  RT R2RR7      hRTRJRTRT/p%TP                  R 4      '       d   ^ R!I1H2p&  T&! TR ,          4      T%R &   T'       d(   / TCR#TR$T'       d   TMR%/CT%R&&   ^ R'I$H3p( T(! TTT4       T	'       d   RT%R(&   / TCTT%/Cp)^ R)I4H5p* T'       dš   ^ R*I$H6p+ TPn                  R+,          S0Pp                   R,\        TP                  R4      ;'       g    R-4      R.,           2,          p,T+! S0TT,4       \        4       Ps                  4       Pu                  R/\        T4       R0T, R124        T*! TS0TT)RTR27        RRR4       \        4       P{                  S04      '       g   \|        P                  R4X4       \        4       P�                  S0\        4       Ps                  4       4       \        4       Pƒ                  S04      p-S0T-T-P                  R4      ;'       g    S0Pp                  3#   \         d+   p\        4       P	                  \        T4      RR7      ThRp?ii ; iu upi   \         d+   p\        4       P	                  \        T4      RR7      ThRp?ii ; i  \         d(   p'\        4       P	                  RT R"T' 2RR7      T'hRp'?'ii ; i  \v         d1   p'\        4       P	                  RT R3T' 2\y        T'4      R7      T'hRp'?'ii ; i  + '       g   i     ELŸ; i)6uË  Clone a Git plugin and atomically record its source and exact revision.

*reviewed_pin* is the curated-catalog sha for this install; the scan trusts the tree
only when the checked-out revision is exactly that sha (an annotated-tag pin is peeled to
its commit first â€” HEAD can only ever be the commit). *python_deps* False refuses active
replacements; it never bypasses PM dependency admission. *assume_deps_consent* is the
caller's ``--yes-deps`` answer carried into the publication consent gate, so a headless
install of an active replacement is not refused non-interactively (#122134). *catalog*
(``{"name", "repo", "tier", "pin"}``) is recorded on the install-metadata record with the
checked-out sha â€” provenance lives OUTSIDE the plugin tree, so a repo cannot forge it;
its ``pin`` is kept only when the checkout satisfies it (a ``--ref`` install is off-pin).
*allow_removed* records that the user knowingly bypassed the kill list.
*before_swap(manifest, tree)* runs on the manifest-checked clone BEFORE the security scan, so
the single scan and portable-package check admit the merged tree (file-count/size limits
included). It may return the relative paths it merged in, which a scan block then attributes,
and may raise :class:`PluginOperationError` to abort (re-pin consent). *accept_caution* decides a
caution scan verdict on its own when *force* only means "replace the existing tree" (an update's
re-clone); None lets *force* decide both, as ``install --force`` does.NÚinvalid_sourcer®   ÚsourceÚpinnedTÚrevisionz	.install-)ÚprefixÚdirÚpluginrV   Ú/)Úis_junctionrè   z,' is already installed outside the catalog: z is a link to z2. Delete that link to install the catalog version.Úalready_installedrT   )Ú_carry_user_filesÚ_local_changesc                ó   <€ S! SVS4      # r=   r   )Ú	_manifestrã   r>  ÚlocalrO   s   &&€€€r   Ú_carryÚ$_install_plugin_core.<locals>._carry¹  s   ø€ Ù(¨°°uÓ=Ð=r    )r/  r'  r(  ©Úenabled_plugin_dirs)Ú
installingzx--no-deps cannot replace an active plugin. Retry without --no-deps; PM must prepare its dependencies before publication.)Úcli_command_name)Ú	repo_rootz.' already exists. Use force reinstall or run `z plugins update z`.zl' is pinned. Reinstall it with an explicit --ref <40-character commit SHA> to change its source or revision.Ú
update_url)Úhttps_update_urlz' ÚshaÚpinr„   r+  )Úwrite_catalog_sidecar_recordr,  )Úpublish_plugin)Ú_stash_local_fileszplugins-backupÚ-ÚoldºNé   Nz[yellow]Local edits to z9 tracked file(s) were not carried over; copies are under z (re-apply by hand).[/yellow])Úrequire_consentÚassume_consentz' was not published: z>%s has no plugin.yaml / __init__.py; may not be a valid pluginéÿÿÿÿ)Br5   Ú_normalize_exact_revisionÚ_resolve_git_urlrî   r¯   r   Ú_plugins_dirÚ_canonical_sourceÚ_read_install_metadataÚvaluesr&   Úlenr·   ÚtempfileÚTemporaryDirectoryr   Ú_clone_plugin_repoÚ_resolve_git_executabler   Ú_git_resolve_commitÚ_resolve_subdir_withinrá   rÀ   ÚrstripÚrsplitÚ_repo_name_from_urlÚpm.filesystemr<  Ú
is_symlinkr�   rÂ   ÚrealpathÚ_sanitize_plugin_namer±   rÅ   rN   Úhermes_cli.plugins_cmd_catalogr>  r?  Ú_scan_merged_treerf   rF  Úresolverú   r¤   Úpm.environmentsrH  Úpm.pathsrI  Úhermes_cli.plugins_updatesrK  rN  Úhermes_cli.plugins_transactionrO  rP  rí   rV   r£   r'   r_   Ú_publish_failure_classÚ_looks_like_plugin_dirrº   r»   Ú_copy_example_filesÚ_read_manifest)1r—   r/  r%  r&  r'  r(  r)  r*  r+  r,  r-  Úrequested_revisionÚgit_urlÚsubdirÚerË   r5  Úold_metadataÚpinsÚtmpÚ	tmp_cloneÚinstalled_revisionÚgit_exeÚat_reviewed_pinÚ
tmp_targetrM   rq   Úlinkr<  ÚpriorÚtracked_editsr?  rC  ÚmergedrF  rH  rI  ÚrecordrK  rj   rN  Únew_metadatarO  rP  ÚbackupÚinstalled_manifestr>  rB  rO   s1   &$$$$$$$$$$                                   @@@r   Ú_install_plugin_corer‹  f  sI  ú€ ð@ BEÂœ›×8Ñ8¸Ô=ÐVZÐðXÜ›%×0Ñ0°Ó<‰ˆô “%×$Ñ$Ó&€KÜ‹U×$Ñ$ WÓ5€FÜ“5×/Ñ/Ó1€Lð Ò!Ø'×.Ñ.Ô0ÓjÑ0�a·E±E¸(³OÀvÑ4M”ÐRS×RWÑRWÐX`ÓRaÐeiÐRi—�Ñ0ˆÐjÜˆt‹9˜Œ>œj¨¨a­¯©°ZÓ)@Ä#×FÒFÜ!$£×!@Ñ!@ÀÀaÅÈÕATÓ!UÐä	×	$Ò	$¨K¸[×	IÕ	IÈSÜ˜“I Õ(ˆ	Ü ›U×5Ñ5°iÀÐ^dÓeÐÜ“%×/Ñ/Ó1ˆÜ˜|Ó,÷ wð wÐ1CßKR×WcŒC‹E×%Ñ% i°¸,ÔGÐiuñ2wˆçHN”S“U×1Ñ1°)¸VÔDÐT]ˆ
Ü˜j¨+Ô6Ü-¨jÓ9ˆØ—l‘l 6Ó*÷ eð eß5;ˆF�M‰M˜#Ó×%Ñ% c¨1Ó-¨bÖ1ÄÃ×AZÑAZÐ[bÓAcð 	àœS Ó-Õ-ˆÝ-Ø”c˜+Ó&Ô&¨D¯O©O×,=Ò,=ÁÈT×ARÒARô “%×,Ñ,Ø˜;˜-Ð'SÐTXÐSYÐYgÜ—7‘7×#Ñ# DÓ)Ð*Ð*\ð^à1ð -ó 3ð 3ð	^Ü“U×0Ñ0°¸kÓJˆFô 	  ¨+Ô6Ø× Ñ  Ó-ˆð $&ˆØÒ§E¨f¯m©m¯oªoÀf×FWÑFW×FYÒFYÜ˜u¤d×+Ò+°·	±	¸(Ó0CÀvÔ0MßXÙ#1°&Ó#9Ñ ˆE�=÷>à ˆKð 7BÒ6M‘˜X zÔ2ÐSWˆä‹×Ñ 
¨J¸È~ÒOeÁeÐkyØ1AÐP_ð 	 ô 	açÝ8à�~‰~ÓÑ#6À&Ô#IÔIÜ“e×0Ñ0ðKØZmð 1ó oð oô 	,¨K¸ÔDà�=‰=�?Š?§5Ý8Ý*ä“%×,Ñ,Ø˜;˜-ð (Ù+©I«KÓ8Ð9Ð9IÈ+ÈÐVXðZà1ð -ó 3ð 3ð �=‰=�?Š?Ð1Ò9¼jÈÔPT×>UÒ>UÐZ_×ZcÑZcÐdlÓZmÐquÓZuÜ“%×,Ñ,Ø˜;˜-ð (Tð TØcvð -ó xð xð
 Ð(°Ð4ØÐ*Ø�fð%
ˆð �<‰<˜×%Ò%ÝCð}Ù'7¸ÀÕ8NÓ'O��|Ñ$÷ ð!Øð!àÐ)Ø§‘|¸Bñ!ˆF�9Ñõ
 TÙ(¨°WÐ>PÔQßØ&*ˆF�?Ñ#Ø<˜,Ð<¨°VÑ<ˆÝAçÝIà ×'Ñ'Ð*:Õ:ÀÇÁ¸}ÈAÌcÐRW×R[ÑR[Ð\fÓRg×RpÐRpÐkpÓNqÐrtÕNuÐMvÐ=wÕwˆFÙ˜v }°fÔ=Ü‹E�N‰NÓ×"Ñ"Ø)¬#¨mÓ*<Ð)=ð >$Ø$* 8Ð+HðJôKð	aÙ˜: v¨|¸\Ð[_Ø*=ö?÷Q 
Jô\ ‹5×'Ñ'¨×/Ò/Ü�‰ÐWÐYdÔeÜƒE×Ñ˜f¤c£e§n¡nÓ&6Ô7Ü›×-Ñ-¨fÓ5ÐØÐ%Ð'9×'=Ñ'=¸fÓ'E×'TÐ'TÈÏÉÐTÐTøôA ô XÜ‹e×(Ñ(¬¨Q«Ð?OÐ(ÓPÐVWÐWûðXüò køô4 ô 	^Ü“%×,Ñ,¬S°«VÐCUÐ,ÓVÐ\]Ð]ûð	^ûôp ô }Ü“e×0Ñ0°8¸K¸=ÈÈ3È%Ð1PÐ`rÐ0ÓsÐy|Ð|ûð}ûô8 ô 	aÜ“%×,Ñ,¨x¸°}ÐDYÐZ]ÐY^Ð-_Ü;QÐRUÓ;Vð -ó XØ]`ðaûð	aú÷U 
J×	IÐ	Iús  ¤[1 Â\)Â:\)Ã\)ÅA!_Æ>_Ç&_Ç-A
_È8_ÉA>_Ë _ËA_Ì\.Ì+*_Í_Í,_ÎB_ÐA&_Ñ.A_Ó A._Ô/_Ô6]&Õ_Õ_Õ _Õ?_ÖA_×A_Ø4^Û1\&Û<%\!Ü!\&Ü.]#Ü9%]Ý]#Ý#_Ý&^Ý1"^Þ^Þ_Þ_Þ&+_ß_ß_ß_*	c               ó    € V ^8„  d   QhRRRR/# )r   rj   ÚBaseExceptionr   r   r   )r   s   "r   r   r     s   € ÷ ñ  ð °#ñ r    c                ó(  € ^ RI Hp \        V \        4       P                  4      '       d	   V! V 4      MRpV'       d
   VR8w  d   V# \        V \
        4      '       d   R# \        V \        4      '       d   \        V \        \        34      '       g   R# R# )aƒ  Why publication failed, from the exception TYPE at this raise site. Publication is the PM
dependency sync (plugins_transaction.publish_plugin -> pm.client.sync_venv): a consent refusal
keeps the class plugins_transaction tagged, a filesystem error keeps its kind, and everything
else PM raised (InstallError, ResolutionConflict, AdmissionRefused, a worker error) is a
dependency failure.)Útagged_failure_classNÚotherrÔ   Úfilesystem_errorÚdeps_failed)	Ú.hermes_cli.observability.shared_metrics_fieldsr�  r·   r5   r¯   ÚPermissionErrorr×   ÚConnectionErrorÚTimeoutError)rj   r�  Útaggeds   &  r   rs  rs    sm   € õ Tä*4°S¼#»%×:TÑ:T×*UÒ*UÑ! #Ô&Ð[_€Fß�&˜GÔ#ØˆÜ�#”×'Ò'ÙÜ�#”w×Ò¬
°3¼Ì,Ð8W×(XÒ(XÙ!Ùr    c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   ÚinstallzCallable[[], tuple]Úcatalog_namer1  r—   r   r   r   r   )r   s   "r   r   r      s+   € ÷ ñ Ð1ð ÀMð Ð_bð Ðglñ r    c          	     ó   € ^ RI Hp V'       d   RMVP                  R4      '       d   RMRp\        \	        4       P                  4       4      p V ! 4       pT^,          T9  d   T! RYAR
R7       T#   \         d   pT! RYARTR7       h R	p?ii ; i)z÷Run one plugin install attempt (a core ``(target, manifest, installed_name)`` call) and record
it as a shared-metrics extension install: failed when it raises, success unless it replaced an
already-installed plugin (a reinstall is not an install).)Úrecord_extension_installr+  úfile://rB  r…   r:  Úfailed)Úkindr5  rV   Úoutcomer  NÚsuccess)rŸ  r5  rV   r   )Ú.hermes_cli.observability.shared_metrics_eventsrœ  Ú
startswithr   r5   r\  r_   )r™  rš  r—   rœ  r5  Úbeforerø   rj   s   &$$     r   Úrecorded_installr¥     sŠ   € õ Xç&‰Y¸
×8MÑ8MÈi×8XÒ8X©WÐ^c€FÜ”“×-Ñ-Ó/Ó0€FðÙ“ˆð ˆa…y˜ÔÙ  h°vÐZcÕdØ€Møô ô Ù  h°vÐZbÐjmÕnØûðús   ÁA0 Á0BÁ;BÂBc               ó$   € V ^8„  d   QhRRRRRR/# )r   r—   r   r”   r   r   ztuple[Optional[Any], str]r   )r   s   "r   r   r   2  s"   € ÷ +ñ + ð +¸ð +ÐB[ñ +r    c          	     ór  € ^ RI Hp VP                  V 4      '       g   VP                  R4       RV 3# VP	                  W4      pVP                  RVP
                   RVP                   RVP                  R,           R24       V'       g!   VP                  VP                  V4      4       WDP                  3# )	z³``(catalog entry or None, install identifier)``, printing where the install comes from: the
catalog pin (plus the entry's description unless *brief*) or the custom-source warning.©Úplugins_cmd_cataloguU   [yellow]Warning:[/yellow] custom (unreviewed) source â€” not from the Hermes catalog.Nz[bold]z[/bold] [cyan]\[z][/cyan] [dim]pinned @ rS  r$   )
r4   r©  Úlooks_like_catalog_namer'   Úresolve_catalog_namerV   ÚtierrL  Úentry_capability_summaryÚinstall_identifier)r—   r-   r”   r+  rþ   s   &&$  r   Ú_announce_sourcer¯  2  s£   € õ :Ø×*Ñ*¨:×6Ò6Ø�‰ÐmÔnØ�ZÐÐØ×(Ñ(¨Ó=€EØ‡M�M�F˜5Ÿ:™:˜,Ð&7¸¿
¹
°|ÐCZÐ[`×[dÑ[dÐegÕ[hÐZiÐioÐpÔqßØ�‰�g×6Ñ6°uÓ=Ô>Ø×*Ñ*Ð*Ð*r    c               ó<   € V ^8„  d   QhRRRRRRRRR	RR
RRRRRRR/	# )r   r—   r   r/  r   Úenabler0  r&  r1  r,  Úno_depsÚyes_depsr”   r   r   r   )r   s   "r   r   r   @  sm   € ÷ Qñ QØðQàðQð ðQð 
ð	Qð
 ðQð ðQð ðQð ðQð 
ñQr    c           
     óL	  a aaaaaaaa€ ^ RI Ho \        4       P                  4       p\	        S W‡R7      w  oo S'       d   VP                  R4        \        4       P                  S 4      w  ršS'       g+   SP                  ! S V	.S'       d   SP                  3MR1O5!   X	P                  R24      '       d   TP                  R4       T'       g&   TP                  RT	 X
'       d   RT
 R	2MR
 R24       \        TR4      oR TTTTTT TTT3	R llp \        TSe   SP                  MRS R7      w  rÞp\        4       P#                  X4      '       g   TP                  RX R24       \%        XT4       ^ RIHp TP+                  4       T! 4       9   pS'       d   RMTpS'       d   TP                  R4       ^ RIHp T! T4      pTfT   T'       gL   \        4       P1                  4       ;'       d,    \        4       P3                  T'       d   RX R2MRX R24      pRRppT'       d   T'       g   \5        YíTSR7      w  pp\        4       P7                  TS TR7       T'       d3   T'       g+   TP                  R X R!T 24       TP                  R"4       RpT'       d#   T'       d	   T'       g   TP                  R#4       MwT'       d   \9        TP                  TTR$7       MVT'       d:   ^ R%IHp  \        4       P?                  XRTR&7       TP                  R'T R(24       MTP                  R)X R*24       ^ R+I H!p T! T4      ;p'       d   TP                  R,T R-24       \        4       PE                  TX4      pT'       d   \        4       PG                  Y�TR.R/7       T'       d   T'       g   ^ R0I$H%p T! Y�4       TP                  4        R#   \        \        4       P                  3 d)   p\        4       P                  TRT 24        Rp?ELsRp?ii ; i  \        4       P                   dR   p\        4       P                  TR\        T\        4       P                   4      '       d   RMR RT 24        Rp?ELLRp?ii ; i  T d    TP                  R"4        ELki ; i)3a  Install a plugin from the curated catalog (bare name), a Git URL, or owner/repo shorthand.

A catalog hit installs the reviewed pinned SHA and records catalog membership in the shared install
metadata. An explicit different ``--ref`` is a custom pin. URLs/shorthand are custom sources. Every
install is checked against the catalog kill list unless *allow_removed*.
*enable* None prompts "Enable now? [y/N]"; True/False skip the prompt.
*yes_deps* is ``--yes-deps``: the explicit answer to the Python-deps consent
question, so non-interactive installs (SSH automation, CI, Docker entrypoints)
finish in one run instead of being refused and left for an ``enable`` that
cannot recover a refused publication (#122134). The default without it stays
fail-closed in non-interactive sessions.
*brief* is for a caller that already told the user what is being installed and why (first-time
setup): the catalog line, questions, warnings, errors and the outcome print, the catalog
description, clone line and default "Installed" panel do not.
r¨  )r”   už   [bold red]WARNING:[/bold red] [red]--allow-removed set â€” skipping the catalog kill-list check. This plugin may have been removed for security reasons.[/red]z[red]Error:[/red] Nzs[yellow]Warning:[/yellow] Using insecure/local URL scheme. Consider using https:// or git@ for production installs.z[dim]Cloning z
 (subdir: Ú)r„   z	...[/dim]ÚInstallc               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r   s   "r   r   Ú!cmd_install.<locals>.__annotate__p  s   € ÷ `ñ `�eñ `r    c            
     ó�   <	€ Se   SP                  SSSSS S'       * SR7      # \        4       P                  SSSS S'       * SSR7      # )N)r/  r&  r,  r'  r)  r*  )r/  r&  r'  r)  r,  r*  ©Úinstall_catalog_entryr5   r‹  )	Ú_interactive_scan_decisionr,  r+  rþ   r/  r—   r²  r&  r³  s	   €€€€€€€€€r   Ú_installÚcmd_install.<locals>._installp  sh   ø€ ØÒØ×0Ñ0Ø˜U¨¸=Ð[uØ 'œK¸Xð 1ó Gð Gô ‹u×)Ñ)Ø˜e¨Ð?YØ#œ°=ÐV^ð *ó `ð 	`r    ©rš  r—   z[red]ÚBlockedÚErrorz:[/red] z[yellow]Warning:[/yellow] z_ doesn't contain plugin.yaml, plugin.json, or __init__.py. It may not be a valid Hermes plugin.rE  FzM[dim]--no-deps: skipping dependency consent; the plugin stays disabled.[/dim])Ú_defines_memory_providerz  Use 'z%' as the memory provider now? [y/N]: z
  Enable 'z' now? [y/N]: Tr[   u#   [red]âœ—[/red] Cannot enable [bold]z	[/bold]: z[[dim]The plugin stays installed but disabled; re-enable after resolving the conflict.[/dim]zC[dim]Replacement installed; plugin selection was not changed.[/dim])Úselect©ÚAdmissionRefused)r±  r-   u    [green]âœ“[/green] Plugin [bold]z[/bold] enabled.zB[dim]Plugin installed but not enabled. Run `hermes plugins enable z` to activate.[/dim])Úrequires_auth_noticez[yellow]z	[/yellow]r™  )Úcontext)Úreport_activationr   ©zhttp://r�  )&r4   r©  r5   r£   r¯  r'   rY  Úraise_if_removedrV   rî   r¯   Ú_failr£  r  r¥  r·   ÚPluginScanBlockedrt  r“   rf   rF  rn  Úplugins.memoryrÃ  r
  r  ro   r¨   Ú_select_memory_providerÚhermes_cli.plugins_admissionrÆ  Ú_set_plugin_enabledÚ#hermes_cli.plugin_provider_requestsrÇ  Ú$_declared_capabilities_from_manifestÚ_run_capability_consentÚhermes_cli.plugins_activationrÉ  )r—   r/  r±  r&  r,  r²  r³  r”   r-   rx  Ú_subdirrz  r¾  rO   rŠ  Úinstalled_namerF  Úalready_activeÚshould_enablerÃ  Úis_memory_providerÚdeps_okÚdeps_reasonrÆ  rÇ  ÚnoticeÚdeclared_capsrÉ  r½  r+  rþ   s   ff&ffff&                    @@@r   Úcmd_installrß  @  s!  ÿø€ õ2 :Ü‹e�n‰nÓ€GÜ(¨°WÔJÑ€Eˆ:ßØ�‰ðLô	Mð7Ü›5×1Ñ1°*Ó=ÑˆßØ×$Ò$ Z°Ð\ÏU¸U¿Z¹Z¹MÐXZÔ\ð ×ÑÐ0×1Ò1Ø�‰ðGô	H÷ Ø�‰˜ g YÏ'°¸G¸9ÀAÑ/FÐWYÐ.ZÐZcÐdÔeÜ!:¸7ÀIÓ!NÐ÷`÷ `ð `ðtÜ5EØ°Ò1B 5§:¢:ÈÐYcô6eÑ2ˆ Nô ‹5×'Ñ'¨×/Ò/Ø�‰Ø(¨Ð(8ð 9Pð Qô	Rô Ð.°Ô8å0ð —^‘^Ó%Ñ)<Ó)>Ñ>€Nß$‘E¨&€MßØ�‰ÐeÔfõ 8Ù1°&Ó9ÐØÒ§^Ü›Ÿ™›÷ >ð >¬C«E¯N©NßOaˆg�nÐ%Ð%JÑKØ˜nÐ-¨^Ð<ó->ˆð ! $ˆ[€GßŸ^Ü:Ð;MÐW^ØFNô PÑˆ�ô ƒE× Ñ  ¨¸5Ð ÔA÷ ŸWð 	�‰Ø1°.Ð1AÀØˆmðô	
ð 	�‰ð2ô	
ð ˆ÷ ×1·fØ�‰Ð[Õ\ß	Ü §¡¨W¸]ÖKß	ÝAð
	Ü‹E×%Ñ% n¸TÈ7Ð%ÔSð �M‰MØ2°>Ð2BÐBRÐSõð 	�‰ð*Ø*8Ð)9Ð9MðOô	Põ IÙ%Ð&8Ó9Ð9€vÖ9Ø�‰˜  ¨	Ð2Ô3ä“E×>Ñ>Ð?QÐSaÓb€MßÜ‹×%Ñ% g¸}ÐV_Ð%Ô`ß×(åCÙ˜'Ô2Ø‡M�M†OøôY œ›×2Ñ2Ð3ô 7Ü‹�‰�GÐ1°!°Ð5×6Ò6ûð7ûô. ‹5×%Ñ%ô tÜ‹�‰�G˜u´*¸QÄÃ×@WÑ@W×2XÒ2X¡YÐ^eÐ$fÐfnÐopÐnqÐr×sÒsûðtûðx  ô 	Ø�M‰Mð6÷ð	úsI   Á9O ÂO Ä!P Ë0R ÏPÏ/PÐPÐRÐ3AQ?Ñ?RÒR#Ò"R#c               ó$   € V ^8„  d   QhRRRRRR/# )r   rV   r   rÄ  r   r   r   r   )r   s   "r   r   r   Ô  s&   € ÷ %Sñ %S #ð %S¸4ð %SÀDñ %Sr    c          	     ó–  € V'       g   VP                  RV  R24       R# ^ RIHp ^ RIHp V! V 4      f   VP                  RV  R24       R#  V! V 4       ^ RIH	p \        4       P                  4       p\        4       P                  4       \        4       P                  T 4      r˜Y‰,          '       d@    \        4       P                  \        4       P                  4       Y‰,
          TRT  R2TR7       \        4       P!                  4       p
\        4       P#                  T 4       TP                  RT  RT
'       d   Y 8w  d   RT
 R2MR RT  R24       R#   \
         dL   p\        P                  RT R	R
7       TP                  RT  RT 24       TP                  R4        Rp?R# Rp?ii ; i  T d    TP                  R4        R# i ; i)z¨Make *name* the live memory provider (deps prepared through PM first, as ``hermes memory setup``
does), or say how to; ``plugins enable`` cannot activate one (#119909).zb[dim]Memory provider installed but not active. Run `hermes memory setup` (or set memory.provider: z) to use it.[/dim]N)Ú$prepare_memory_provider_dependencies)Úfind_provider_diru   [red]âœ—[/red] zE does not resolve as a memory provider; memory.provider is unchanged.z0memory provider %s dependency preparation failedT)Úexc_infou!   [red]âœ—[/red] Could not prepare z's dependencies: zV[dim]memory.provider is unchanged; run `hermes memory setup` after resolving it.[/dim]rÅ  zRe-enable 'Ú')r-   ÚactionÚexpected_configz([dim]memory.provider is unchanged.[/dim]u   [green]âœ“[/green] [bold]z[/bold] set as memory.providerz (replacing rµ  r„   z. Run `hermes memory setup z'` to configure it; new sessions use it.)r'   Úhermes_cli.memory_setuprâ  rÎ  rã  r_   rº   ÚdebugrÐ  rÆ  r5   Ú_plugin_selection_versionÚ_get_disabled_setÚ_plugin_aliasesÚ_admit_and_save_plugin_setsÚ_get_enabled_setÚ_get_current_memory_providerÚ_save_memory_provider)rV   r-   rÄ  râ  rã  rj   rÆ  rç  ÚdisabledÚaliasesÚpreviouss   &&$        r   rÏ  rÏ  Ô  s¹  € ÷ Ø�‰ð(Ø(, vÐ-?ðAô	Bñ 	ÝLÝ0Ù˜ÓÒ&Ø�‰˜¨ vÐ-rÐsÔtÙðÙ,¨TÔ2õ >Ü“e×5Ñ5Ó7€OÜ›×/Ñ/Ó1´3³5×3HÑ3HÈÓ3NˆgØ×Ôð	Ü‹E×-Ñ-¬c«e×.DÑ.DÓ.FÈÕHZØ6=ÈÐTXÐSYÐYZÐF[Ø>Mð .ô Oô ‹u×1Ñ1Ó3€HÜƒE×Ñ Ô%Ø‡M�MØ
# D 6Ð)Gß)1°hÔ6Fˆ\˜(˜ 1Ñ%ÈBÐ
Oð P$Ø$( 6Ð)Pð	RöSøô' ô Ü�‰ÐGÈÐX\ˆÔ]Ø�‰Ð9¸$¸Ð?PÐQTÐPUÐVÔWØ�‰ÐnÔoÝûð	ûð  ô 	Ø�M‰MÐDÔEÚð	ús+   ÁE Â3>F, ÅF)ÅA F$Æ$F)Æ,GÇGc               ó$   € V ^8„  d   QhRRRRRR/# )r   rš  r   r&  r1  r   zOptional[tuple]r   )r   s   "r   r   r   ü  s&   € ÷ tñ t¨3ð t°]ð tÀñ tr    c                óº  € ^ RI Hp \        4       P                  V 4      pVf   R# V'       d<   \	        V! V4      R,          4      P                  4       VP                  4       8w  d   R# \        4       P                  V4      pVP                  R4      ;'       g    VP                  pWSP                  0\        4       P                  4       ,          '       d   R# W4V3# )aü  ``(target, manifest, installed_name)`` of the installed, not enabled tree whose install record
names catalog entry *catalog_name*, else None. A refused enable leaves the published clone in
place (there is no rollback), so the card's Try again, or the model asking again, stopped at
"already exists" on a second clone and the plugin could never be turned on from the card.
Like ``hermes plugins enable``, the tree is used at the commit it has; an explicit *ref* only
matches a tree checked out at that commit.)Úcatalog_install_recordNrL  rV   )
rl  rö  r5   Ú_catalog_installed_dirr   r*   rv  r&   rV   rî  )rš  r&  rö  rO   rM   r×  s   &&    r   Ú_catalog_install_on_diskrø  ü  s¨   € õ FÜ‹U×)Ñ)¨,Ó7€FØ‚~Ùß
ŒsÑ)¨&Ó1°%Õ8Ó9×?Ñ?ÓAÀSÇYÁYÃ[ÔPÙÜ‹u×#Ñ# FÓ+€HØ—\‘\ &Ó)×8Ð8¨V¯[©[€NØ"§K¡KÐ0´3³5×3IÑ3IÓ3K×KÔKˆ4ÐsÐRXÐdrÐQsÐsr    c               ó$   € V ^8„  d   QhRRRRRR/# )r   r—   r   rš  r1  r   r   r   )r   s   "r   r   r     s!   € ÷ -ñ - ð -°=ð -ÀUñ -r    c           
     óP  € ^ RI Hp . pRpV'       dJ   VP                  V4      pVf   RWRRRRV R2/3# VP                  \	        V4      4       VP
                  p MVP                  R4        \        4       P                  V 4      ^ ,          pVP                  R
4      '       d   VP                  R	4       VP                  ! W.V'       d   VP                  3MRO5!   Y@TR3#   \         d     L\        4       P                   d   pY@TRRR\        T4      /3u Rp?# Rp?ii ; i)z¯``(entry, identifier, warnings, error)``: the catalog entry (None for a custom source), the
identifier to clone, the warnings so far, and the refusal result when there is one.r¨  Nr  Fr  rå  z&' is not in the Hermes plugin catalog.u;   Custom (unreviewed) source â€” not from the Hermes catalog.zEInsecure URL scheme; prefer https:// or git@ for production installs.rÊ  r   )r4   r©  Úget_live_catalog_entryrÖ   r   r®  r|   r5   rY  r£  rË  rV   rî   r¯   r   )r—   rš  r+  rx   rþ   rx  rj   s   &&     r   Ú_resolve_sourcerü    s  € õ :Ø€HØ€EßØ×.Ñ.¨|Ó<ˆØŠ=Ø˜°°e¸WÈÈ,ÈÐW}ÐF~Ð/ÐÐØ�‰Ô-¨eÓ4Ô5Ø×-Ñ-‰
à�‰ÐUÔVðMÜ“%×(Ñ(¨Ó4°QÕ7ˆØ×ÑÐ4×5Ò5Ø�O‰OÐcÔdØ× Ò  ÐXÏ¸¿¹¹ÐTVÔXð
 ˜h¨Ð,Ð,øô	 ô ÙÜ‹5×%Ñ%ô MØ (¨T°5¸'Ä3ÀsÃ8Ð,LÐLÕLûðMús%   Á.A1C$ Ã$D%Ã1D%Ä	D ÄD%Ä D%c               ó0   € V ^8„  d   QhRRRRRRRRRR	R
R/# )r   r—   r   r/  r   r&  r1  r*  ÚstepúCallable[[InstallPhase], None]r   ztuple | dictr   )r   s   "r   r   r   (  s9   € ÷ 0ñ 0 3ð 0°$ð 0¸]ð 0Ðaeð 0Ø4ð0Ø9Eñ0r    c               óþ  a aaaaa	€ ^ RI Ho	 S;'       g    RP                  4       ;'       g    RoS e   S'       g   \        S P                  S4      MRpVe   V# R VV	V VVV3R llpV! \
        P                  4        \        TS e   S P                  MRSR7      #   \        4       P                   d   p\        T4      u Rp?# Rp?i\        4       P                   d   pRRR	\        T4      /u Rp?# Rp?ii ; i)
a  ``(target, manifest, installed_name)`` of the tree to enable, or the error result. A catalog
entry already on disk and not enabled (an earlier enable was refused) is used as it is, unless
an approved *ref* names another commit; a fresh install clones at *ref* when set, else the pin.r¨  r„   Nc               ó   € V ^8„  d   QhRR/# r¸  r   )r   s   "r   r   Ú!_place_tree.<locals>.__annotate__3  s   € ÷ uñ u�eñ ur    c                 ór   <€ Se   SP                  SSSRS R7      # \        4       P                  SSSS R7      # )NF)r/  r&  r,  r*  )r/  r&  r*  r»  )r*  r+  rþ   r/  r—   r&  s   €€€€€€r   r¾  Ú_place_tree.<locals>._install3  sL   ø€ ØÒØ×0Ñ0°¸eÈÐ\aØEXð 1ó Zð Zä‹u×)Ñ)¨*¸EÀsÐ`sÐ)ÓtÐtr    rÀ  r  Fr  )r4   r©  r)   rø  rV   r   Údownloadingr¥  r5   rÍ  r$  r¯   r   )
rþ   r—   r/  r&  r*  rþ  Úon_diskr¾  rj   r+  s
   ffddd$   @r   Ú_place_treer  (  sÓ   ý€ õ
 :Ø�9ˆ9�"×
Ñ
Ó
×
%Ð
% €CØ;@Ò;L×UZÔ& u§z¡z°3Ô7Ð`d€GØÒØˆ÷uõ uñ 	Œ×	!Ñ	!Ô"ð0Ü ÀUÒEV°u·z²zÐ\`Ø+5ô7ð 	7øä‹5×"Ñ"ô (Ü" 3Ó'Õ'ûÜ‹5×%Ñ%ô 0Ø�e˜W¤c¨#£hÐ/Õ/ûð0ús0   Â B ÂC<Â7
CÃC<ÃC<Ã#C7Ã1C<Ã7C<c               ó$   € V ^8„  d   QhRRRRRR/# )r   r×  r   rþ  rÿ  r   r2  r   )r   s   "r   r   r   C  s#   € ÷ ñ  3ð Ð4Rð ÐWeñ r    c           	     óÈ   € ^ RI Hp V'       d   V! \        P                  4        \	        4       P                  V RR7       R
#   T d   pRRRRT 2RT R	R/u R
p?# R
p?ii ; i)zwNone once enabled, else the refusal result. Enabling admits the plugin, and admission resolves
its Python dependencies.rÅ  T)r±  r  Fr  zenable refused: rq   ÚenabledN)rÐ  rÆ  r   Úpython_packagesr5   rÑ  )r×  ri   rþ  rÆ  rj   s   &&&  r   Ú_enable_placedr  C  sm   € õ >çÙŒ\×)Ñ)Ô*ðqä‹×!Ñ! .¸Ð!Ô>ñ øð ô qØ�e˜WÐ(8¸¸Ð&>ÀÈ~Ð_hÐjoÐpÕpûðqús   ¦A ÁA!Á
AÁA!ÁA!rš  Úon_stepc               ó8   € V ^8„  d   QhRRRRRRRRRRR	R
RRRR/# )r   r—   r   r/  r   r±  rš  r1  r&  r*  r0  r  z(Optional[Callable[[InstallPhase], None]]r   r  r   )r   s   "r   r   r   R  sP   € ÷ (ñ (Øð(Ø#ð(Ø-1ð(ØANð(à	ð(à4Bð(ð 6ð(ð ñ	(r    c               óÎ  € Vf   T;'       d    V'       * pT;'       g    R p\        W4      w  r€ršV
e   V
# \        W€WWWR7      p\        V\        4      '       d   V# Vw  rÍp\	        4       P                  WÉ4      pV'       d   \        WïV4      ;p'       d   V# TR,          p^ RIHp V'       d   V! \        P                  4       V'       d	   V! V4      MRRRRR	R/pR
RRTRT	RTR\	        4       P                  V4       Uu. uF  pVR,          NK  	  upRVP                  4       '       d   \        V4      MRRV/VCRV'       d   \        VP                  4      /C# . /C# u upi )aò  Non-interactive install for the dashboard/TUI. *catalog_name* installs a curated entry at its
pinned SHA (identifier may be empty); *ref* pins either source to one full commit SHA (same
contract as ``--ref``); every path enforces the kill list (no GUI bypass). *assume_deps_consent*
is consent the caller holds for the Python deps, so no terminal is needed to answer the gate.
None (a user's Install click) is the consent the fresh-install enable already acts on: a plugin
the config already selects (``memory.provider``) would otherwise be refused every time, while
the same plugin unselected installs and enables. A forced replacement still needs explicit consent.
*on_step* hears each slow phase as it starts (the catalog card draws it under its bar).Nc                ó   € R # r=   r   )Ú_phases   &r   Ú<lambda>Ú*dashboard_install_plugin.<locals>.<lambda>a  s   € ¡dr    )r/  r&  r*  rþ  r›   )Úactivate_plugin_nowÚgateway_reloadedFÚ
activationÚrestart_requiredr  Trq   rx   Úpython_dependenciesÚmissing_envrV   Úafter_install_pathr
  rý   )rü  r  r·   rN   r5   r}   r  rÕ  r  r   Úloading_toolsr‰   r¤   r   r{   rý   )r—   r/  r±  rš  r&  r*  r  rþ  rþ   rx   r  ÚplacedrO   rŠ  r×  ri   ÚrefusedÚapr  Ú	activatedÚss   &$$$$$$              r   Údashboard_install_pluginr!  R  sy  € ð Ò"Ø$×2Ð2¨U¬ÐØ×+Ð+Ñ*€DÜ)8¸Ó)RÑ&€E�xØÒØˆÜ˜°%ÐViÔu€FÜ�&œ$×ÒØˆØ17Ñ.€F Ü‹5×+Ñ+¨FÓ=€Dßœn¨^À4ÓHÐH�7ÖHØˆØ	Ð$Õ	$€Bõ BßÙŒ\×'Ñ'Ô(ß7=Ñ# NÔ3Ø˜E <°Ð7IÈ5ðDR€Ið 	ˆd�M >°:¸xØ˜tØ¬3«5×+CÑ+CÐDVÔ+WÓXÑ+W a˜˜&Ÿ	˜	Ñ+WÑXØ¨¯©¯ªœc "œg¸$À	È6ð	ð V_ð	ð
 	·Eœ˜U×/Ñ/Ó0ñð ð
 @Bñð ùò Ys   ÄE")FNNFFFF)8Ú__conditional_annotations__rH   Ú
__future__r   Úloggingr�   rb   r_  Ú
contextlibr   Úcontextvarsr   Úpathlibr   Útypingr   r   r	   Úhermes_cli.cli_outputr
   Úhermes_cli.plugin_install_phaser   Ú	getLoggerrD   rº   r   Ú__annotations__r   r0   r5   r   r7   ro   rg   r}   r“   r¨   r±   rÀ   rÈ   rá   rú   r   r  r$  r‹  rs  r¥  r¯  rß  rÏ  rø  rü  r  r  r!  )r"  s   @r   Ú<module>r-     s²  øðôõ #ã Û 	Û 
Û Ý %Ý "Ý ß *Ñ *å ,Ý 8à	×	Ò	˜8Ó	$€ñ /9Ð9TÐ^bÔ.c€Ð+Ó cð ñ%ó ð%õòô�cô ð0kØAF÷0kðf)ØLQ÷)õXõð@Èu÷ õ$Gõõ4õõ:
õ2EõõðcUð &*ð	cUð
 ðcUð ðcUð #'ðcUð ðcUð !&ðcUð #ðcUð  ðcUð ÷cUõNõ&õ$+÷Qõh%SõPtõ$-õ40õ6ð(ØQUð(àð(àEIð(ð 9=÷(ñ (r    