Ë
    âß²jÏ@  ã                  ó¦  — U d Z ddlmZ ddlZddlZddlZddlZddlZddl	Z	ddl
mZ ddlmZ ddlmZmZmZmZmZ ddlmZ  ej,                  dd	d
«      Zej1                  «       ZdZdZh d£Z G d„ de«      Z ed¬«       G d„ d«      «       Z ej@                  «       Z!da"de#d<   d3d„Z$d4d„Z%d5d6d„Z&d5d7d„Z'd8d„Z(d9d„Z) ej@                  «       Z*i Z+de#d<   d:d„Z,d5d;d„Z- ej@                  «       Z.i Z/d e#d!<   d<d"„Z0d5d#d$œd=d%„Z1d&Z2d3d'„Z3d>d(„Z4d?d)„Z5d5d@d*„Z6dd+œdAd,„Z7dd+œdBd-„Z8 e9«       Z:d.e#d/<    e;d0«      jy                  e=«      Z>dCd1„Z?dDd2„Z@y)EuÁ  Plugin compatibility with the Sep 2026 decomposition: detect, warn, and (after the date) disable.

The decomposition (PR #102117) moved most of Hermes's internals into ``<stem>_<topic>`` sibling modules.
Old import paths keep resolving through ``PLUGIN-COMPAT`` blocks until :data:`COMPAT_REMOVAL_DATE`, when
the commit that added them is reverted. This module is the single source of truth for everything that
tells plugin authors and users about that:

* :func:`scan_plugin` â€” static AST scan of one plugin directory for imports of manifest names.
* :func:`compat_report` â€” ``{plugin_name: [Hit, ...]}`` across the user's ENABLED external plugins, cached.
* :func:`removal_in_effect` â€” True once today >= the removal date (or the layer is already gone).
* :func:`warn_once` â€” the per-name runtime warning emitted by the PLUGIN-COMPAT ``__getattr__`` blocks.

Surfaces that read from here: the CLI banner, ``hermes plugins compat``, ``hermes doctor``, the post-update
notices, the TUI/Desktop ``plugins.compat_report`` RPC, and ``PluginManager`` (which skips a hitting plugin
after the date unless ``plugins.allow_deprecated_imports: true``).

This module is part of the compat layer and is removed with it.
é    )ÚannotationsN)Ú	dataclass)ÚPath)ÚDictÚIterableÚListÚOptionalÚTuple)Úatomic_json_writeiê  é	   é   Úallow_deprecated_importszcompat_manifest.json>   ú.gitú.venvÚtestÚvenvÚtestsÚ__pycache__Únode_modulesc                  ó   — e Zd ZdZy)ÚHermesPluginCompatWarningz@A plugin imported a name from its pre-decomposition module path.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    ú=/home/ubuntu/.hermes/hermes-agent/hermes_cli/plugin_compat.pyr   r   '   s   „ ÚJr   r   T)Úfrozenc                  ó6   — e Zd ZU ded<   ded<   ded<   ded<   y)ÚHitÚstrÚfileÚintÚlineÚoldÚnewN)r   r   r   Ú__annotations__r   r   r   r!   r!   +   s   … à
ƒIØ
ƒIØ	ƒHØ	„Hr   r!   ú#Optional[Dict[str, Dict[str, str]]]Ú_manifest_cachec                 ór   — t        t        «      j                  «       j                  j                  t        z  S ©N)r   Ú__file__ÚresolveÚparentÚ_MANIFEST_NAMEr   r   r   Úmanifest_pathr1   9   s&   € Ü”‹>×!Ñ!Ó#×*Ñ*×1Ñ1´NÑBÐBr   c                 ó  — t         5  t        �t        cddd«       S i } t        «       }|j                  «       r£	 t	        j
                  |j                  d¬«      «      d   D ]v  }|j                  d«      xs d}|j                  d«      r|d   › d	|d
   › d�}n$|j                  d	|d
   z   «      r|}n
|› d	|d
   › �}|| j                  |d   i «      |d
   <   Œx 	 | a| cddd«       S # t        $ r i } Y Œw xY w# 1 sw Y   yxY w)zS``{facade_module: {name: new_dotted_path}}``; ``{}`` when the compat layer is gone.Núutf-8)ÚencodingÚentriesÚtargetÚ ú(Úfacadeú.Únameu,    (removed; no replacement â€” vendor a copy))Ú_manifest_lockr*   r1   ÚexistsÚjsonÚloadsÚ	read_textÚgetÚ
startswithÚendswithÚ
setdefaultÚ	Exception)ÚoutÚpÚer6   r'   s        r   Úload_manifestrI   =   s  € ô 
ñ ÜÐ&Ü"÷ñ ð *,ˆÜ‹OˆØ�8‰8Œ:ðÜŸ™ A§K¡K¸ KÓ$AÓBÀ9ÑMò E�AØŸU™U 8›_Ò2°�FØ×(Ñ(¨Ô-Ø!" 8¡ ¨Q¨q°©y¨kÐ9eÐf™ØŸ™¨¨q°©y©Ô9Ø$™à!' ¨¨!¨F©)¨Ð5˜ØAD�C—N‘N 1 X¡;°Ó3°A°f±IÒ>ñEð ˆØ÷'ñ øô  ò Ø’ðú÷!ð ús4   ‡C:�C:ºB!C)ÃC:Ã)C7Ã4C:Ã6C7Ã7C:Ã:Dc                ó†   — t        «       j                  «       sy| xs t        j                  j	                  «       t
        k\  S )zaTrue when hitting plugins must be disabled: the date has passed or the layer is already reverted.T)r1   r=   Ú_dtÚdateÚtodayÚCOMPAT_REMOVAL_DATE©rM   s    r   Úremoval_in_effectrP   V   s/   € ä‹?×!Ñ!Ô#ØØÒ%”S—X‘X—^‘^Ó%Ô*=Ñ=Ð=r   c                óh   — t         | xs t        j                  j                  «       z
  j                  S r,   )rN   rK   rL   rM   ÚdaysrO   s    r   Údays_until_removalrS   ]   s#   € Ü 5Ò#<¬C¯H©H¯N©NÓ,<Ñ=×CÑCÐCr   c              #  ó   K  — t        j                  | «      D ]]  \  }}}|D �cg c]  }|t        vsŒ|j                  d«      rŒ|‘Œ! c}|d d  |D ]$  }|j	                  d«      sŒt        |«      |z  –— Œ& Œ_ y c c}w ­w)Nr:   z.py)ÚosÚwalkÚ
_SKIP_DIRSrB   rC   r   )ÚrootÚdpÚdnsÚfnsÚdÚfs         r   Ú_iter_pyr^   c   su   è ø€ ÜŸ™ ›ò #‰ˆˆC�Ø ÖR˜ A¬ZÒ$7ÀÇÁÈSÕ@Q’!ÒRˆ‰AˆØò 	#ˆAØ�z‰z˜%Õ Ü˜2“h ‘lÓ"ñ	#ñ#ùÚRùs!   ‚!A>£A9±A9ÁA9ÁA>Á$A>c                óŽ  — 	 t        j                  | «      }g }i }t        j                  |«      D �]$  }t	        |t         j
                  «      r¥|j                  |v r—|j                  dk(  rˆ|j                  D ]x  }|j                  ||j                     v sŒ|j                  t        ||j                  |j                  › d|j                  › �||j                     |j                     «      «       Œz ŒÃt	        |t         j                  «      sŒÞ|j                  D ]8  }|j                  |v sŒ|j                  ||j                  xs |j                  <   Œ: �Œ' t        j                  |«      D �]®  }t	        |t         j                  «      r®t	        |j                   t         j"                  «      rŠ|j                   j$                  |v rr||j                   j$                     }|j&                  ||   v sŒ…|j                  t        ||j                  |› d|j&                  › �||   |j&                     «      «       ŒÌt	        |t         j                  «      �rg }	|}
t	        |
t         j                  «      rB|	j                  |
j&                  «       |
j                   }
t	        |
t         j                  «      rŒBt	        |
t         j"                  «      s�Œc|	j                  |
j$                  «       |	j)                  «        t+        dt-        |	«      «      D ]Z  }dj/                  |	d| «      |	|   }}||v sŒ!|||   v sŒ)|j                  t        ||j                  |› d|› �||   |   «      «       Œ\ �Œt	        |t         j0                  «      s�Œt	        |j                   t2        «      s�Œ:d|j                   v s�ŒJ|j                   j5                  d«      \  }}}||v s�Œo|||   v s�Œx|j                  t        ||j                  |j                   ||   |   «      «       �Œ± t7        t9        |«      d„ ¬«      S # t        $ r g cY S w xY w)z›Hits in one file: ``from F import n``, ``import F`` + ``F.n``, ``import F as a`` + ``a.n``,
    and string targets ``"F.n"`` (``patch``/``import_module``).r   r:   é   Nc                óH   — | j                   | j                  | j                  fS r,   )r#   r%   r&   )Úhs    r   ú<lambda>zscan_source.<locals>.<lambda>•   s   € ¨A¯F©F°A·F±F¸A¿E¹EÐ+B€ r   )Úkey)ÚastÚparseÚSyntaxErrorrV   Ú
isinstanceÚ
ImportFromÚmoduleÚlevelÚnamesr;   Úappendr!   ÚlinenoÚImportÚasnameÚ	AttributeÚvalueÚNameÚidÚattrÚreverseÚrangeÚlenÚjoinÚConstantr"   Ú
rpartitionÚsortedÚset)ÚsrcÚrelÚmanifestÚtreeÚhitsÚaliasesÚnodeÚaÚfacÚpartsÚcurÚiÚmodr;   Ú_s                  r   Úscan_sourcerŒ   k   s_  € ðÜ�y‰y˜‹~ˆð €DØ €GÜ—‘˜“ó 9ˆÜ�dœCŸN™NÔ+°·±¸xÑ0GÈDÏJÉJÐZ[ÊOØ—Z‘Zò q�Ø—6‘6˜X d§k¡kÑ2Ò2Ø—K‘K¤ C¨¯©¸¿¹¸ÀQÀqÇvÁvÀhÐ6OÐQYÐZ^×ZeÑZeÑQfÐgh×gmÑgmÑQnÓ oÕpñqô ˜œcŸj™jÕ)Ø—Z‘Zò 9�Ø—6‘6˜XÒ%Ø23·&±&�G˜AŸH™HÒ.¨¯©Ò/ò9ð9ô —‘˜“ó TˆÜ�dœCŸM™MÔ*¬z¸$¿*¹*ÄcÇhÁhÔ/OÐTX×T^ÑT^×TaÑTaÐelÑTlØ˜$Ÿ*™*Ÿ-™-Ñ(ˆCØ�y‰y˜H S™MÒ)Ø—‘œC  T§[¡[°S°E¸¸4¿9¹9¸+Ð2FÈÐQTÉÐVZ×V_ÑV_ÑH`ÓaÕbÜ˜œcŸm™mÕ,à!ˆEØˆCÜ˜S¤#§-¡-Ô0Ø—‘˜SŸX™XÔ&Ø—i‘i�ô ˜S¤#§-¡-Õ0ô ˜#œsŸx™xÖ(Ø—‘˜SŸV™VÔ$Ø—‘”Ü˜q¤# e£*Ó-ò a�AØ #§¡¨¨r°¨Ó 3°U¸1±X˜�CØ˜h’¨4°8¸C±=Ò+@ØŸ™¤C¨¨T¯[©[¸S¸EÀÀ4À&¸/È8ÐTWÉ=ÐY]ÑK^Ó$_Õ`òaô ˜œcŸl™lÖ+´
¸4¿:¹:ÄsÖ0KÐPSÐW[×WaÑWaÓPaØŸ:™:×0Ñ0°Ó5‰LˆC��DØ�h‹ 4¨8°C©=Ó#8Ø—‘œC  T§[¡[°$·*±*¸hÀs¹mÈDÑ>QÓRÖSð-Tô0 ”#�d“)Ñ!BÔCÐCøôK ò ØŠ	ðús   ‚P6 Ð6QÑQz=Dict[str, Tuple[Tuple[Tuple[str, int, int], ...], List[Hit]]]Ú_scan_cachec                ó  — g }t        | «      D ]S  }	 |j                  «       }|j                  t	        |j                  | «      «      |j                  |j                  f«       ŒU t        t        |«      «      S # t        $ r Y Œuw xY w)uª   ``(relpath, mtime_ns, size)`` of every ``.py`` under the plugin â€” the cache key for a scan.
    A stat walk costs ~1 ms; the AST scan it replaces costs ~10 ms per file.)
r^   ÚstatÚOSErrorrm   r"   Úrelative_toÚst_mtime_nsÚst_sizeÚtupler|   )Ú
plugin_dirÚsigrG   Ústs       r   Ú_plugin_dir_signaturer˜   œ   s   € ð €CÜ�jÓ!ò Qˆð	Ø—‘“ˆBð 	�
‰
”C˜Ÿ™ jÓ1Ó2°B·N±NÀBÇJÁJÐOÕPðQô ”˜“ÓÐøô ò 	Ùð	ús   ’A8Á8	BÂBc                ó–  — t        «       }|€|n|}||u }|r| rt        | «      j                  «       sg S t        | «      } t        | j	                  d¬«      «      }|rt        | «      nd}|r<t        5  t        j                  |«      }ddd«       �|d   |k(  rt        |d   «      S g }t        | «      D ]C  }	 |j                  dd¬	«      }	|t        |	|j                  | «      j                  «       |«      z  }ŒE |r%t        5  |t        |«      ft        |<   ddd«       |S |S # 1 sw Y   Œ�xY w# t        $ r Y Œ†w xY w# 1 sw Y   |S xY w)
u  Hits for one plugin directory. With the default manifest the result is cached process-wide
    on the directory's file signature: a multiplex gateway discovers plugins once per served
    profile, and re-parsing every plugin's source per profile was ~0.4s Ã— profiles on the boot path.NF)Ústrictr   r   r`   r3   Úreplace)r4   Úerrors)rI   r   Úis_dirr"   r.   r˜   Ú
_scan_lockr�   rA   Úlistr^   r@   r�   rŒ   r‘   Úas_posix)
r•   r€   ÚloadedÚ	cacheablerd   Ú	signatureÚcachedr‚   rG   r~   s
             r   Úscan_pluginr¥   ©   sY  € ô ‹_€FØ!Ð)‰v¨x€HØ˜FÐ"€IÙ™:¬T°*Ó-=×-DÑ-DÔ-FØˆ	Ü�jÓ!€JÜ
ˆj× Ñ ¨Ð Ó.Ó
/€CÙ5>Ô% jÔ1ÀB€IÙÜñ 	*Ü —_‘_ SÓ)ˆF÷	*àÐ &¨¡)¨yÒ"8Ü˜˜q™	“?Ð"Ø€DÜ�jÓ!ò Qˆð	Ø—+‘+ w°y�+ÓAˆCð
 	”˜C §¡¨zÓ!:×!CÑ!CÓ!EÀxÓPÑP‰ðQñ Üñ 	7Ø )¬4°«:Ð6ŒK˜Ñ÷	7à€Kˆ4€K÷!	*ð 	*ûô ò 	Ùð	ú÷	7à€Kús*   Á1D#Â8D/ÄD>Ä#D,Ä/	D;Ä:D;Ä>Ez+Dict[Tuple[str, ...], Dict[str, List[Hit]]]Ú_report_cachec                óÐ  — t        | dd«      dk(  st        | dd«      syt        | j                  «      }t        | dd«      dk(  rnddl}	 |j                  j                  |j                  d«      d   «      }t        |d	d«      }|r|d
v ryt        |«      }|j                  dk(  r|j                  S dS t        |«      }|j                  «       r|S dS # t        t        f$ r d}Y Œnw xY w)ux  Directory to scan for ONE manifest, or None when there is nothing safe to scan.

    Directory plugins carry their own dir. Entry points carry ``module:attr``: resolve the module
    through import metadata to its installed package dir. Never fall back to a relative path â€” that
    made ``C:\...`` and ``pkg:attr`` scan the CWD and attribute stray files to the plugin.
    Úsourcer7   ÚbundledÚpathNÚ
entrypointr   ú:Úorigin)zbuilt-inr   z__init__.py)Úgetattrr"   rª   Úimportlib.utilÚutilÚ	find_specÚ	partitionÚImportErrorÚ
ValueErrorr   r;   r/   r�   )r€   ÚrawÚ	importlibÚspecr­   rG   s         r   Ú
_scan_rootr¸   Ï   så   € ô ˆx˜ 2Ó&¨)Ò3¼7À8ÈVÐUYÔ;ZØÜ
ˆh�m‰mÓ
€CÜˆx˜ 2Ó&¨,Ò6Ûð	Ø—>‘>×+Ñ+¨C¯M©M¸#Ó,>¸qÑ,AÓBˆDô ˜˜x¨Ó.ˆÙ˜Ð#9Ñ9ØÜ�‹LˆØŸ6™6 ]Ò2ˆq�x‰xÐ<¸Ð<ÜˆS‹	€AØ—‘”
ˆ1Ð$ Ð$øô œZÐ(ò 	ØŠDð	ús   Á	-C ÃC%Ã$C%F)Úforcec               ó°  — | €O	 ddl m}  |«       }|j                  «        |j                  j	                  «       D �cg c]  }|j
                  ‘Œ } }| D �cg c]#  }t        |dd«      dk7  sŒt        |dd«      sŒ"|‘Œ% }}t        t        d„ |D «       «      «      }t        5  |s|t        v rt        |   cddd«       S ddd«       t        «       }i }	|D ])  }t        t        |«      |«      }
|
sŒ|
|	|j                  <   Œ+ t        5  |	t        |<   ddd«       t!        |	«       |	S c c}w # t        $ r i cY S w xY wc c}w # 1 sw Y   ŒƒxY w# 1 sw Y   Œ=xY w)	zÍ``{plugin_name: hits}`` for every ENABLED external (non-bundled) plugin with at least one hit.

    ``manifests`` defaults to the current PluginManager's discovered manifests. Cached per manifest set.
    Nr   )Úget_plugin_managerr¨   r7   r©   rª   c              3  óR   K  — | ]  }|j                   › d |j                  › �–— Œ! y­w)ú@N)r;   rª   )Ú.0Úms     r   ú	<genexpr>z compat_report.<locals>.<genexpr>ö   s#   è ø€ Ò>°˜!Ÿ&™&˜  1§6¡6 (Ô+Ñ>ùs   ‚%')Úhermes_cli.pluginsr»   Údiscover_and_loadÚ_pluginsÚvaluesr€   rE   r®   r”   r|   Ú_report_lockr¦   rI   r¥   r¸   r;   Ú_write_report_file)Ú	manifestsr¹   r»   ÚmgrÚlpr¿   Úexternalrd   r€   rF   r‚   s              r   Úcompat_reportrË   è   sQ  € ð
 Ðð	Ý=Ù$Ó&ˆCØ×!Ñ!Ô#Ø/2¯|©|×/BÑ/BÓ/DÖE¨˜Ÿ›ÐEˆIÐEð %Ök�a¬°°8¸RÓ(@ÀIÓ(MÔRYÐZ[Ð]cÐeiÕRj’Ðk€HÐkÜ
”Ñ>°XÔ>Ó>Ó
?€CÜ	ñ &Ù˜¤Ñ-Ü  Ñ%÷&÷ &ñ &ô ‹€HØ "€CØò ˆÜœ: a›=¨(Ó3ˆÚØˆC�—‘ŠKðô 
ñ !Ø Œ�cÑ÷!ä�sÔØ€Jùò# FøÜò 	ØŠIð	üâk÷&ð &ú÷!ð !úsL   „9D* ½D%ÁD* ÁD;Á,D;Á:D;Â!E Ä
EÄ%D* Ä*D8Ä7D8Å E	ÅEz.plugin-compat-report.jsonc                 ó*   — ddl m}   | «       t        z  S )Nr   ©Úget_hermes_home)Úhermes_constantsrÎ   ÚREPORT_FILErÍ   s    r   Úreport_file_pathrÑ   	  s   € Ý0ÙÓœ{Ñ*Ð*r   c                óî  — 	 t        «       }| s!|j                  «       r|j                  «        yt        t	        «       t
        j                  j                  t
        j                  j                  «      j                  d¬«      | j                  «       D ���ci c]   \  }}||D �cg c]  }|j                  ‘Œ c}“Œ" c}}}t        | «      dœ}t        ||d¬«       yc c}w c c}}}w # t        $ r Y yw xY w)a#  Persist the latest report for surfaces without a Python runtime handy (the Desktop boot modal).

    Written on every scan so a fixed plugin clears the notice on the next start; removed outright when
    there is nothing to report so a stale file can never resurface a resolved warning.
    NÚseconds)Útimespec)Úremoval_dateÚ	in_effectÚ
written_atÚpluginsÚlinesr`   )Úindent)rÑ   r=   ÚunlinkÚCOMPAT_REMOVALrP   rK   ÚdatetimeÚnowÚtimezoneÚutcÚ	isoformatÚitemsÚ__dict__Úsummary_linesr   rE   )ÚreportrG   ÚkÚvrb   Úpayloads         r   rÆ   rÆ     sÃ   € ðÜÓˆÙØ�x‰xŒzØ—‘”
ØÜ#1Ô@QÓ@SÜ!$§¡×!1Ñ!1´#·,±,×2BÑ2BÓ!C×!MÑ!MÐW`Ð!MÓ!aØFLÇlÁlÃn×UÐU¹d¸aÀ˜q°qÖ"9°! 1§:£:Ò"9Ñ9ÔUÜ)¨&Ó1ñ3ˆô 	˜!˜W¨QÖ/ùò #:ùÔUøô ò Ùðús;   ‚,C( ¯A(C( ÂC!Â$CÂ7C!Â<C( ÃC!Ã!C( Ã(	C4Ã3C4c                ó*   — t        t        | «      «      S )z?Hits for ONE manifest (used by the loader before importing it).)r¥   r¸   )r€   s    r   Úplugin_hitsrê   #  s   € ä”z (Ó+Ó,Ð,r   c                óž   — 	 | €ddl m}  |«       } | xs i j                  d«      xs i j                  t        d«      du S # t        $ r Y yw xY w)zX``plugins.allow_deprecated_imports: true`` keeps hitting plugins loading after the date.r   )Úload_config_readonlyrØ   FT)Úhermes_cli.configrì   rA   Ú	ALLOW_KEYrE   )Úconfigrì   s     r   r   r   (  sU   € ðØˆ>Ý>Ù)Ó+ˆFà’˜2×"Ñ" 9Ó-Ò3°×8Ñ8¼ÀEÓJÈdÐRÐRøÜò Ùðús   ‚=A  Á 	AÁArO   c               ó„   — t        |«      r
t        «       ryt        | «      }|sydt        |«      › dt        › dt
        › d�S )z]Why the loader must skip this plugin now, or None. Only ever non-None after the removal date.Nzuses z import path(s) removed on zN; run `hermes plugins compat` for the list, update the plugin, or set plugins.z: true to force-load)rP   r   rê   rx   rÜ   rî   )r€   rM   r‚   s      r   Údisable_reasonrñ   4  sP   € ä˜UÔ#Ô'?Ô'AØÜ�xÓ €DÙØØ”C˜“I�;Ð9¼.Ð9Ið J?Ü?H¸kÐI]ð_ð `r   c               óÔ  — | sg S t        | «      }dj                  d„ t        | j                  «       «      D «       «      }t	        |«      r/t        «       r%|› d|dk7  rdnd› dt        › dt        › d	|› �	}d
}||gS t	        |«      r&|› d|dk7  rdnd› dt        › d	|› �}dt        › d�}||gS t        |«      }|› d|dk7  rdnd› d|dk(  rdnd› dt        › d|› d|dk7  rdnd› d|› �}d}||gS )zIPlain-text lines for banners/notices; empty when there is nothing to say.z, c              3  óD   K  — | ]  \  }}|› d t        |«      › d�–— Œ y­w)ú (ú)N)rx   )r¾   ræ   rç   s      r   rÀ   z summary_lines.<locals>.<genexpr>D  s%   è ø€ ÒK©D¨A¨q˜˜˜2œc !›f˜X QÔ'ÑKùs   ‚ z pluginr`   Úsr7   z force-loaded via plugins.z: they import paths removed on z: zSUpdate the plugin(s); the old paths no longer exist. Details: hermes plugins compatz( DISABLED: they import paths removed on z$Update the plugin(s) or set plugins.z4: true to force-load. Details: hermes plugins compatz usez# import paths that stop working on rô   z dayz): zYCheck for plugin updates or notify the author before then. Details: hermes plugins compat)	rx   ry   r|   râ   rP   r   rî   rÜ   rS   )rå   rM   Únrl   ÚheadÚtailr\   s          r   rä   rä   ?  s?  € áØˆ	ÜˆF‹€AØ�I‰IÑK´F¸6¿<¹<»>Ó4JÔKÓK€EÜ˜ÔÔ$<Ô$>Ø�#�W A¨¢F™S°Ð3Ð3MÌiÈ[ð YÜ,Ð-¨R°¨wð8ˆàdˆð �$ˆ<Ðô 
˜5Ô	!Ø�#�W A¨¢F™S°Ð3Ð3[Ô\jÐ[kÐkmÐnsÐmtÐuˆØ5´i°[Ð@tÐuˆð �$ˆ<Ðô	 ˜uÓ%ˆØ�#�W A¨¢F™S°Ð3°4¸qÀAºv¹È2Ð7NÐNqÜ!Ð" " Q C t°1¸²6©C¸rÐ+BÀ#ÀeÀWðNˆàjˆØ�$ˆ<Ðr   r}   Ú_seenÚloggingc           	     óö   — | |f}|t         v ryt         j                  |«       ||k7  r|› d|› �n|› d|› �}d| › d|› d|› dt        › d�	}t        j	                  |«       t        j                  |t        d¬«       y)	a¦  Per-name record that a moved name was resolved through its old path: a ``HermesPluginCompatWarning``
    (so ``-W error`` catches it in tests and plugin authors' CI) plus a WARNING log line (agent.log /
    gateway.log). The interactive CLI hides the warning category from stderr (:func:`quiet_for_interactive`)
    because its banner carries the user-facing message with the plugin NAME, which this call site cannot know.Nr:   zhermes plugin compat: `z` moved to `zD`. The old path is kept only for external plugins and is removed on z; update your import.é   )Ú
stacklevel)rú   ÚaddrÜ   Ú_logÚwarningÚwarningsÚwarnr   )r9   r;   Útarget_moduleÚtarget_namerd   r'   Úmsgs          r   Ú	warn_oncer  Z  s�   € ð
 �4ˆ.€CØ
Œe�|ØÜ	‡I�Iˆc„NØ.9¸TÒ.Aˆ]ˆO˜1˜[˜MÑ
*È-ÈÐXYÐZ^ÐY_ÐG`€CØ$ V H¨A¨d¨V°<À¸uð E(Ü(6Ð'7Ð7LðN€Cä‡L�L�ÔÜ‡M�M�#Ô0¸QÖ?r   c                 ó~   — t        d„ t        j                  D «       «      st        j                  dt        d¬«       yy)zÌCalled by the interactive CLI before plugin discovery: the banner notice replaces raw stderr warnings.
    Appends (does not override) so an explicit ``-W error::...HermesPluginCompatWarning`` still wins.c              3  ób   K  — | ]'  \  }}}}}|d k(  xr |duxr t        t        |«      –— Œ) y­w)ÚerrorN)Ú
issubclassr   )r¾   r…   Ú_mÚcÚ_modÚ_ls         r   rÀ   z(quiet_for_interactive.<locals>.<genexpr>m  s@   è ø€ ò ;Ù%�1�b˜!˜T 2ð �G‰|ÒZ ¨ ÒZ´*Ô=VÐXYÓ2ZÓZñ ;ùs   ‚-/ÚignoreT)Úcategoryrm   N)Úanyr  ÚfiltersÚfilterwarningsr   r   r   r   Úquiet_for_interactiver  j  s8   € ô ñ ;Ü)1×)9Ñ)9ô;ô ;ä×Ñ Ô3LÐUYÖZð;r   )Úreturnr   )r  úDict[str, Dict[str, str]]r,   )rM   úOptional[_dt.date]r  Úbool)rM   r  r  r$   )rX   r   r  zIterable[Path])r~   r"   r   r"   r€   r  r  ú	List[Hit])r•   r   r  z Tuple[Tuple[str, int, int], ...])r•   úOptional[Path]r€   r)   r  r  )r  r  )r¹   r  r  úDict[str, List[Hit]])rå   r  r  ÚNone)r  r  )rï   zOptional[dict]r  r  )rM   r  r  zOptional[str])rå   r  rM   r  r  z	List[str])
r9   r"   r;   r"   r  r"   r  r"   r  r  )r  r  )Ar   Ú
__future__r   re   rÝ   rK   r>   rU   Ú	threadingr  Údataclassesr   Úpathlibr   Útypingr   r   r   r	   r
   Úutilsr   rL   rN   rá   rÜ   rî   r0   rW   ÚFutureWarningr   r!   ÚLockr<   r*   r(   r1   rI   rP   rS   r^   rŒ   rž   r�   r˜   r¥   rÅ   r¦   r¸   rË   rÐ   rÑ   rÆ   rê   r   rñ   rä   r}   rú   Ú
__import__Ú	getLoggerr   r   r  r  r   r   r   ú<module>r(     s  ðòõ$ #ã 
Û Û Û 	Û Û Ý !Ý ß 8Õ 8Ý #à�c—h‘h˜t Q¨Ó+Ð Ø$×.Ñ.Ó0€Ø&€	Ø'€ÚV€
ôK ô Kñ �$Ô÷ð ó ðð  �—‘Ó!€Ø7;€Ð4Ó ;óCóô2>ôDó#ó*DðZ ˆY�^‰^Ó€
ØMO€ÐJÓ Oó
ôðD ˆy�~‰~Ó€Ø=?€Ð:Ó ?ó%ð2°5õ ð< +€ó+ó
ó*-ô
	ð =Aõ `ð PTõ ñ. ‹U€€sÓ Ù�)Ó×&Ñ& xÓ0€ó@ô [r   