Ë
    ãß²j­Ë  ã                   óH  — U d 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ZddlZddl	m
Z
 ddlmZmZmZ ddlmZ ddlmZ ddlmZmZmZ dZdddd	œd
edee   dee   dee   dee   f
d„Z ej6                  «       Z e«       Zeeeeef      e d<   dZ!dedededefd„Z"dedee   dedeeeeef   df   fd„Z#deeeeef   df   de$fd„Z%deeeeef   df   ddfd„Z&dZ' ejP                  d«      Z)dedeeee   f   fd„Z* ejP                  d «      Z+d!edeeef   fd"„Z,d#edeee-ef   dz  fd$„Z. ejP                  d%«      Z/d&ede$fd'„Z0d(ee   de$fd)„Z1ded&edefd*„Z2 ejP                  d+«      Z3d,d-d.œZ4	 d8d/ed0e-d1e-d2e-d3ee   defd4„Z5dee   de$fd5„Z6 G d6„ d7«      Z7y)9z“Content/file search tier for ``tools.file_operations``.

``ShellFileOperations`` inherits ``SearchMixin``; module-level helpers are pure
(no I/O).
é    N)ÚPath)ÚAnyÚListÚOptional)ÚSEARCH_PRUNE_DIR_NAMES)Ú	interrupt)ÚExecuteResultÚSearchMatchÚSearchResult)ÚDesktopÚ	DocumentsÚ	DownloadsÚLibraryÚMoviesÚMusicÚPictures©ÚcwdÚhomeÚplatformÚpathr   r   r   Úreturnc          
      óª  — |xs t         j                  dk7  rg S t        | «      j                  «       }|j	                  «       s$t        |xs t        j                  «       «      |z  }t        t
        j                  j                  t        |«      «      «      }t        t
        j                  j                  t        t        |xs t        j                  «       «      j                  «       «      «      «      }g }t        D ]C  }	 ||z  j                  |«      }|j                  sŒ%|j                  |j!                  «       «       ŒE |S # t        $ r Y ŒSw xY w)a  Protected home dirs (relative to ``path``) below a broad macOS search root.

    Only an ANCESTOR search (``$HOME``, ``/Users``) gets exclusions, so recursive
    tools never trigger unattended TCC prompts; a search rooted inside a
    protected dir stays allowed.
    Údarwin)Úsysr   r   Ú
expanduserÚis_absoluteÚosÚgetcwdr   ÚnormpathÚstrr   Ú_MACOS_TCC_PROTECTED_HOME_DIRSÚrelative_toÚ
ValueErrorÚpartsÚappendÚas_posix)	r   r   r   r   ÚrootÚ	home_pathÚ
exclusionsÚdirnameÚrelatives	            úA/home/ubuntu/.hermes/hermes-agent/tools/file_operations_search.pyÚ"_macos_protected_search_exclusionsr.      s  € ð 	Ò ”C—L‘L XÒ-Øˆ	Ü�‹:× Ñ Ó"€DØ×ÑÔÜ�CÒ&œ2Ÿ9™9›;Ó'¨$Ñ.ˆÜ”—‘× Ñ ¤ T£Ó+Ó,€DÜ”R—W‘W×%Ñ%¤c¬$¨tÒ/B´t·y±y³{Ó*C×*NÑ*NÓ*PÓ&QÓRÓS€IØ€JÜ1ò 3ˆð	Ø! GÑ+×8Ñ8¸Ó>ˆHð �>‹>Ø×Ñ˜h×/Ñ/Ó1Õ2ð3ð Ðøô	 ò 	Ùð	ús   ÄEÅ	EÅEÚ_ACTIVE_FILENAME_SEARCH_ROOTSçš™™™™™©?Úenvr(   Úfallback_cwdc                 ó$  — ddl m}m}m} t	        | dd«      xs |}t        | |«      rª|r ||«      } ||«      }t        j                  j                  |«      s t        j                  j                  ||«      }t        j                  j                  t        j                  j                  t        j                  j                  |«      «      «      S t        j                  |«      st        j                  ||«      }t        j                  |«      S )zFNormalize a filename-walk root without resolving remote paths locally.r   ©ÚLocalEnvironmentÚ_IS_WINDOWSÚ_msys_to_windows_pathr   N)Útools.environments.localr5   r6   r7   ÚgetattrÚ
isinstancer   r   ÚisabsÚjoinÚnormcaseÚabspathr    Ú	posixpath)r1   r(   r2   r5   r6   r7   r   s          r-   Ú _normalized_filename_search_rootr@   =   s¿   € ç]Ñ]ä
�#�u˜dÓ
#Ò
3 |€CÜ�#Ð'Ô(ÙÙ(¨Ó.ˆDÙ'¨Ó,ˆCÜ�w‰w�}‰}˜TÔ"Ü—7‘7—<‘<  TÓ*ˆDÜ�w‰w×Ñ¤§¡§¡´·±×0@Ñ0@ÀÓ0FÓ GÓHÐHÜ�?‰?˜4Ô Ü�~‰~˜c 4Ó(ˆÜ×Ñ˜dÓ#Ð#ó    Úroots.c                 óª   — t        | «      }t        t        |D �ch c]&  }|j                  |j                  t        | ||«      f’Œ( c}«      «      S c c}w )z:Unique backend/root admission keys in deterministic order.)ÚtypeÚtupleÚsortedÚ
__module__Ú__qualname__r@   )r1   rB   r2   Úenv_typer(   s        r-   Ú_filename_search_root_keysrJ   N   sZ   € ä�C‹y€HÜ”àöàð 
×	Ñ	˜h×3Ñ3Ô5UÐVYÐ[_ÐamÓ5nÒoòó ó ð ùò s   š+AÚkeysc                 óœ  ‡ — t         5  t        d„ ‰ D «       «      rht        j                  «       r
	 ddd«       yt         j	                  t
        «       t        j                  «       r
	 ddd«       yt        d„ ‰ D «       «      rŒht        j                  «       r
	 ddd«       yt        j                  ˆ fd„«      cddd«       S # 1 sw Y   yxY w)zCAtomically claim every key, polling for thread-scoped interruption.c              3   ó,   K  — | ]  }|t         v –— Œ y ­w©N)r/   )Ú.0Úkeys     r-   ú	<genexpr>z1_acquire_filename_search_roots.<locals>.<genexpr>Y   s   è ø€ ÒG¸3�#Ô6Ô6ÑGùs   ‚NFc                  ó.   •— t         j                  ‰ «      S rN   )r/   Úupdate©rK   s   €r-   ú<lambda>z0_acquire_filename_search_roots.<locals>.<lambda>a   s   ø€ Ô=Z×=aÑ=aÐbfÓ=g€ rA   )Ú_FILENAME_SEARCH_ADMISSIONÚanyÚtool_interruptÚis_interruptedÚwaitÚ_FILENAME_SEARCH_WAIT_SECONDSÚrun_if_not_interruptedrT   s   `r-   Ú_acquire_filename_search_rootsr]   V   s°   ø€ ä	#ñ 	iÜÑGÀ$ÔGÔGÜ×,Ñ,Ô.Ø÷	ið 	iô '×+Ñ+Ô,IÔJÜ×,Ñ,Ô.Ø÷	ið 	iÜÑGÀ$ÔGÕGô ×(Ñ(Ô*Ø÷	ið 	iô ×4Ñ4Ó5gÓh÷	i÷ 	iò 	iús"   ˆ(C¹.CÁ0CÂCÂ!CÃCc                 óŒ   — t         5  t        j                  | «       t         j                  «        ddd«       y# 1 sw Y   yxY w)zARelease a completed walk and leave no idle per-root state behind.N)rV   r/   Údifference_updateÚ
notify_allrT   s    r-   Ú_release_filename_search_rootsra   d   s4   € ä	#ñ 0Ü%×7Ñ7¸Ô=Ü"×-Ñ-Ô/÷0÷ 0ñ 0ús	   ‡*:ºAziFile search was interrupted while waiting for another filename search on the same root. Retry when ready.z'\n?\[Command timed out after \d+s\]\s*$Úresultc                 ó€   — | j                   dk(  r"t        j                  d| j                  «      dfS | j                  dfS )zIReturn stdout cleaned for parsing and a limit reason for search timeouts.é|   Ú Úsearch_timeoutN)Ú	exit_codeÚ_SEARCH_TIMEOUT_MARKER_REÚsubÚstdout)rb   s    r-   Ú_search_stdout_and_limitrk   r   s<   € à×Ñ˜3ÒÜ(×,Ñ,¨R°·±Ó?ÐAQÐQÐQØ�=‰=˜$ÐÐrA   z0^([A-Za-z]:)?[^\s:][^\n]*?[:\-]\d|^[^\s:][^\s]*$Úoutputc                 óx  — g }g }| j                  d«      D ]�  }|j                  «       sŒ|j                  «       j                  d«      r|j	                  |«       ŒE|dk(  st
        j                  |«      r|j	                  |«       Œq|j	                  |«       Œƒ dj                  |«      dj                  |«      fS )uD  Separate rg/grep diagnostic lines from real match output â†’ ``(diagnostics, payload)``.
    ``_exec`` merges stderr into stdout; classifying by SHAPE lets the exit-2 guard
    tell a pure failure (no payload) from a partial one (one unreadable file, others
    matched) and guarantees error text is never parsed as a match.Ú
)úrg: zgrep: ú--)ÚsplitÚstripÚlstripÚ
startswithr&   Ú_SEARCH_OUTPUT_REÚmatchr<   )rl   ÚdiagnosticsÚpayloadÚlines       r-   Ú_split_tool_diagnosticsrz      s£   € ð
  €KØ€GØ—‘˜TÓ"ò 	%ˆØ�z‰zŒ|Øà�;‰;‹=×#Ñ#Ð$6Ô7Ø×Ñ˜tÕ$Ø�TŠ\Ô.×4Ñ4°TÔ:Ø�N‰N˜4Õ à×Ñ˜tÕ$ð	%ð �9‰9�[Ó! 4§9¡9¨WÓ#5Ð5Ð5rA   ry   c                 óú   — | r| dk(  ryd}t        j                  d| «      D ]  }|}Œ |�|j                  «       dk(  ry| d|j                  «        t        |j	                  d«      «      | |j                  «       d fS )uÚ   Parse a ``path-line-content`` context line using the RIGHTMOST numeric
    separator (filenames may contain ``-<digits>-`` segments):
    ``dir/file-12-name.py-8-context`` â†’ (``dir/file-12-name.py``, 8, ``context``).rp   Nz-(\d+)-r   é   )ÚreÚfinditerÚstartÚintÚgroupÚend)ry   rv   Ú	candidates      r-   Ú_parse_search_context_liner„   “   s}   € ñ �4˜4’<ØØ€EÜ—[‘[ ¨TÓ2ò ˆ	Ø‰ðà€}˜Ÿ™›¨Ò*ØØ��—‘“Ð¤ U§[¡[°£^Ó!4°d¸5¿9¹9»;¸<Ð6HÐHÐHrA   z(?<!\\)(?:\\\\)*\\nÚpatternc                 óJ   — d| v xs t        t        j                  | «      «      S )z¹True when a content regex wants to match a newline: a literal newline or a
    ``\n`` escape with an ODD number of backslashes (``\\n`` is a literal
    backslash+n and must not count).rn   )ÚboolÚ_REGEX_NEWLINE_ESCAPE_REÚsearch)r…   s    r-   Ú_pattern_has_regex_newlinerŠ   ¤   s$   € ð �7ˆ?ÒLœdÔ#;×#BÑ#BÀ7Ó#KÓLÐLrA   Úerrorc                 ó0   — t        | «      xr
 d| v xr d| v S )z@Return True for rg's hard error when multiline mode is required.zliteral "\n" is not allowedú--multiline)r‡   ©r‹   s    r-   Ú_is_line_oriented_newline_errorr�   «   s"   € ä�‹;Ò_Ð;¸uÐDÒ_ÈÐZ_ÐI_Ð_rA   c                 ó    — | j                   dk7  st        |«      s| S | j                  rt        | j                  «      s| S d| _        d| _        | S )zHAttach a newline-regex warning only when search found no usable results.r   Na  0 results found. Note: search_files content search is line-oriented and does not run ripgrep with -U/--multiline, so `\n` in the regex does not match line breaks. Use context=N to inspect neighboring lines, or escape as `\\n` when searching for a literal backslash+n.)Útotal_countrŠ   r‹   r�   Úwarning)rb   r…   s     r-   Ú)_maybe_warn_line_oriented_newline_patternr“   °   sP   € à×Ñ˜QÒÔ&@ÀÔ&IØˆØ‡|‚|Ô;¸F¿L¹LÔIØˆØ€F„Lð	Pð „Nð
 €MrA   z^([A-Za-z]:)?(.*?):(\d+):(.*)$z-lz-c©Ú
files_onlyÚcountÚoutput_modeÚlimitÚoffsetÚcontextr’   c                 ó®  — t        | «      \  }}t        |«      \  }}	| j                  dk(  rP|	j                  «       s@|j                  «       xs | j                  j                  «       xs d}
t        d|
› �d¬«      S |	j                  «       j                  d«      D �cg c]  }|sŒ|‘Œ	 }}|dk(  r(t        ||||z    t        |«      t        |«      ||¬«      S |d	k(  rai }|D ]+  }d
|v sŒ|j                  d
d«      \  }}	 t        |«      ||<   Œ- t        |t        |j                  «       «      t        |«      |¬«      S g }|D ]É  }|dk(  rŒ	t        j                  |«      }|rm|j!                  t#        |j%                  d«      xs d|j%                  d«      z   t        |j%                  d«      «      |j%                  d«      dd ¬«      «       Œ�|dkD  sŒ“t'        |«      }|sŒ¡|j!                  t#        |d   |d   |d   dd ¬«      «       ŒË t        |«      }t        ||||z    ||||z   kD  xs t        |«      ||¬«      S c c}w # t        $ r Y �Œrw xY w)uE  Parse rg/grep ``| head`` output into a SearchResult (shared by both engines).
    Exit codes: 0=matches, 1=none, 2=error â€” but both tools return 2 on PARTIAL
    errors (one unreadable file), so an error is surfaced only when exit==2 AND no
    usable payload remains. ``warning`` is attached to files_only/content results.é   zSearch errorzSearch failed: r   ©r‹   r‘   rn   r•   )Úfilesr‘   Ú	truncatedÚlimit_reasonr’   r–   ú:r|   )Úcountsr‘   rŸ   r    rp   re   é   é   Niô  )r   Úline_numberÚcontent)Úmatchesr‘   rŸ   r    r’   )rk   rz   rg   rr   rj   r   rq   Úlenr‡   Úrsplitr€   r$   ÚsumÚvaluesÚ_MATCH_LINE_RErv   r&   r
   r�   r„   )rb   r—   r˜   r™   rš   r’   rj   r    rw   rx   Ú	error_msgÚlnÚlinesr¢   ry   r   Únr§   ÚmÚparsedÚtotals                        r-   Ú_parse_search_outputr´   Ç   sr  € ô 4°FÓ;Ñ€FˆLÜ2°6Ó:Ñ€K�Ø×Ñ˜1Ò W§]¡]¤_Ø×%Ñ%Ó'ÒR¨6¯=©=×+>Ñ+>Ó+@ÒRÀNˆ	Ü O°I°;Ð"?ÈQÔOÐOØ!Ÿ-™-›/×/Ñ/°Ó5Ö<�BºŠRÐ<€EÐ<Ø�lÒ"ÜØ˜˜v¨™~Ð.¼CÀ»JÜ˜<Ó(°|ÈWôVð 	Vð �gÒØˆØò 	ˆDØ�dŠ{ØŸ+™+ c¨1Ó-‘��aðÜ#& q£6�F˜4’Lð		ô Ø¤s¨6¯=©=«?Ó';Ü˜<Ó(°|ôEð 	Eð €GØò lˆØ�4Š<ØÜ× Ñ  Ó&ˆÙØ�N‰Nœ;Ø—g‘g˜a“jÒ& B¨!¯'©'°!«*Ñ4Ä#ÀaÇgÁgÈaÃjÃ/Ð[\×[bÑ[bÐcdÓ[eÐfjÐgjÐ[kôô ð à�Q‹;Ü/°Ó5ˆFÚØ—‘œ{°°q±	ÀvÈaÁyÐZ`ÐabÑZcÐdhÐehÐZiÔjÕkðlô �‹L€EÜØ˜˜v¨™~Ð.¸EØ˜& 5™.Ñ(Ò>¬D°Ó,>È\Ðcjôð ùòC =øô "ò Úðús   ÂIÂ%IÃ?IÉ	IÉIc                 óP   — t         j                  dk(  xr t        d„ | D «       «      S )zFDarwin-only: every root is POSIX-shaped (no drive letter / backslash).r   c              3   óV   K  — | ]!  }t        j                  d |«       xr d|v–— Œ# y­w)ú^[A-Za-z]:[\\/]ú\N)r}   rv   ©rO   r(   s     r-   rQ   z_posix_roots.<locals>.<genexpr>û   s3   è ø€ ò ,WØHLŒB�H‰HÐ'¨Ó.Ð.ÒC°4¸tÐ3CÓCñ,Wùs   ‚'))r   r   Úall)rB   s    r-   Ú_posix_rootsr»   ù   s1   € ä�<‰<˜8Ñ#ò W¬ñ ,WØPUô,Wó )Wð WrA   c                   ó"  — e Zd ZdZdedee   fd„Z ej                  d«      Z	dedee   fd„Z
	 dAd	ee   d
edededef
d„Zddddœdee   d
edededededefd„Zdedefd„Zdedee   fd„Zdedee   fd„Zdee   deeeeef      fd„Zedee   defd„«       Zedee   defd„«       Zdee   defd „Zdedefd!„Zdedee   fd"„Zdedefd#„Z	 dBd$eded%ed&ee   d'ed(ed)ed*ed+edefd,„Zdedefd-„Z	 dBd$eded%ed&ee   d'ed(ed)ed*ed+edee   fd.„Z defd/„Z!d0Z"d$eded&ee   dee   fd1„Z#dedefd2„Z$	 dBd$edeee   z  d'ed(ed+edefd3„Z%	 dCd$edeee   z  d'ed(ed+ed5ee   defd6„Z&d$eded&ee   d'ed(ed)ed*edefd7„Z'	 	 dDd8ee   d)ed'ed(ed*ed9ee   d:edefd;„Z(	 dEd$eded&ee   d'ed(ed)ed*ed5ee   defd<„Z)	 dEd=ee   d$ed)ed*ed&ee   dee   fd>„Z*d$eded&ee   d'ed(ed)ed*edefd?„Z+d$eded&ee   d'ed(ed)ed*edee   defd@„Z,y4)FÚSearchMixina)  File-name and content search via rg with find/grep fallbacks. Requires
    ``_exec``, ``_has_command``, ``_expand_path``, ``_escape_shell_arg``,
    ``_escape_native_tool_arg``, ``env``, ``cwd``, ``_command_cache``,
    ``_rg_resolution_cache`` and ``_rg_modified_capability`` from the host class.Úcmdr   c           	      ót  — |dk7  r| j                  |«      r|S dS | j                  j                  |«      }|r|S | j                  d«      }|j                  dk(  r]|j
                  j                  «       rC|j
                  j                  «       j                  «       d   }|dk(  rd}|| j                  |<   |S ddlm	}m
} |�rwt        | j                  |«      �r`t        j                  j                  d«      xs t        t!        j"                  «       «      }t        j                  j                  d«      }t        j                  j                  d	«      xs  t        j$                  j'                  |d
«      }	t        j$                  j'                  |ddd«      t        j$                  j'                  |	dd«      g}
|r2|
j)                  t        j$                  j'                  |dddd«      «       |
D ]F  }t        j$                  j+                  |«      sŒ#|j-                  dd«      }|| j                  |<   |c S  y)a   Resolve an executable in the command host's namespace. Ordinary commands
        keep the bool hit/miss cache; rg alone caches successful resolved paths and
        re-probes misses so a mid-session install becomes visible (with off-PATH
        Windows candidates: cargo, scoop, winget).ÚrgNzcommand -v rg 2>/dev/nullr   Úyes)r5   r6   ÚUSERPROFILEÚLOCALAPPDATAÚSCOOPÚscoopz.cargoÚbinzrg.exeÚshimsÚ	MicrosoftÚWinGetÚLinksr¸   ú/)Ú_has_commandÚ_rg_resolution_cacheÚgetÚ_execrg   rj   rr   Ú
splitlinesr8   r5   r6   r:   r1   r   Úenvironr!   r   r   r   r<   r&   ÚisfileÚreplace)Úselfr¾   Úcachedrb   Úresolvedr5   r6   Úuser_profileÚlocal_app_datarÅ   Ú
candidatesrƒ   s               r-   Ú_resolve_commandzSearchMixin._resolve_command  sÃ  € ð
 �$Š;Ø×+Ñ+¨CÔ0�3Ð:°dÐ:Ø×*Ñ*×.Ñ.¨sÓ3ˆÙØˆMØ—‘Ð7Ó8ˆØ×Ñ˜qÒ  V§]¡]×%8Ñ%8Ô%:Ø—}‘}×*Ñ*Ó,×7Ñ7Ó9¸!Ñ<ˆHØ˜5Ò Ø�Ø-5ˆD×%Ñ% cÑ*ØˆOßJâœ: d§h¡hÐ0@ÕAÜŸ:™:Ÿ>™>¨-Ó8ÒL¼CÄÇ	Á	ÃÓ<LˆLÜŸZ™ZŸ^™^¨NÓ;ˆNÜ—J‘J—N‘N 7Ó+ÒR¬r¯w©w¯|©|¸LÈ'Ó/RˆEä—‘—‘˜\¨8°U¸HÓEÜ—‘—‘˜U G¨XÓ6ðˆJñ Ø×!Ñ!¤"§'¡'§,¡,¨~¸{ÈHÐV]Ð_gÓ"hÔiØ'ò $�	Ü—7‘7—>‘> )Õ,Ø(×0Ñ0°°sÓ;�HØ5=�D×-Ñ-¨cÑ2Ø#’Oð	$ð
 rA   a  (?m)^ripgrep\s+((?:0|[1-9]\d*))\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:(?:0|[1-9]\d*)|(?:[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))(?:\.(?:(?:0|[1-9]\d*)|(?:[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\s+\(rev [^)]+\))?\s*$Ú
executablec                 ó`  — || j                   v r| j                   |   S | j                  | j                  |«      › d�d¬«      }| j                  j	                  |j
                  xs d«      }|j                  dk(  r"|r t        |j                  d«      «      dk\  rd}nd	}|| j                   |<   |S )
zHCached actionable error unless rg can sort exactly (full SemVer, >= 14).z
 --versioné
   ©Útimeoutre   r   r|   é   NzeExact modification-time order requires ripgrep 14 or newer; upgrade ripgrep or use order='discovery'.)	Ú_rg_modified_capabilityrÏ   Ú_quote_executableÚ_RG_VERSION_REr‰   rj   rg   r€   r�   )rÔ   rÛ   rb   rv   r‹   s        r-   Ú_modified_rg_capability_errorz)SearchMixin._modified_rg_capability_error4  s¬   € à˜×5Ñ5Ñ5Ø×/Ñ/°
Ñ;Ð;Ø—‘˜t×5Ñ5°jÓAÐBÀ*ÐMÐWY�ÓZˆØ×#Ñ#×*Ñ*¨6¯=©=Ò+>¸BÓ?ˆØ×Ñ˜qÒ ¡U¬s°5·;±;¸q³>Ó/BÀbÒ/HØ‰EðAˆEà38ˆ×$Ñ$ ZÑ0ØˆrA   FÚargvÚfetch_limitrß   Úmerge_stderrc           	      ó  ‡‡‡‡— ddl m}m} t        | j                  dd«      xs | j
                  }t        j                  dj                  |«      «      }	 t        j                  || || j                  j                  «      t        j                  t        j                  |rt        j                  nt        j                  d¬«      Šg Št!        j"                  «       Šdˆˆˆˆfd„}
t!        j$                  |
d¬«      }|j'                  «        t)        j*                  «       |z   }d}	 |j                  d«       |j-                  «       r‰j/                  «       rn2t1        j2                  «       rd}nt)        j*                  «       |kD  rd}nŒd‰j5                  «       € |‰«       ‰j7                  «        |j                  «        ‰j8                  j;                  «        dj                  ‰«      j=                  dd¬«      }|dk(  rt        |d|› d�z   d¬
«      S |dk(  rt        |dz   d¬
«      S t        |‰j/                  «       rd¬
«      S ‰j>                  ¬
«      S # t        $ r}	t        d|	› �d	¬
«      cY d}	~	S d}	~	ww xY w)uù  Run ``argv`` (shell-quoted rg words) natively and stop reading after
        ``fetch_limit`` lines â€” the ``| head -n`` of the shell pipeline without the
        two bash spawns. ``shlex.split`` undoes the escaping the builders apply for
        the shell path, so both transports see identical arguments. Exit code and
        stdout follow the shell contract (rg 0/1/2; 124 on timeout with partial
        output; 130 on interrupt), so ``_parse_search_output`` is shared. Once the
        bound is reached rg is killed like ``head`` closing the pipe would.
        ``merge_stderr`` mirrors the shell path's stderr handling: merged for content
        search (diagnostics feed the error message), discarded (``2>/dev/null``) for
        file lists and probes.r   )Ú_kill_process_group_posixÚ_make_run_envr   NÚ T)r   r1   Ústdinrj   ÚstderrÚstart_new_sessionro   rœ   )rj   rg   c                  óŠ   •— ‰j                   D ]3  } ‰j                  | «       t        ‰«      ‰k\  sŒ#‰j                  «         y  y rN   )rj   r&   r¨   Úset)ÚrawÚboundedræ   r¯   Úprocs    €€€€r-   Ú_drainz*SearchMixin._run_rg_native.<locals>._drain`  s:   ø€ Ø—{‘{ò �Ø—‘˜SÔ!Ü�u“: Ó,Ø—K‘K”MÙñ	rA   )ÚtargetÚdaemonr0   é‚   rd   rA   zutf-8rÓ   )Úerrorsz
[Command timed out after zs]z
[Command interrupted])r   N) r8   ré   rê   r9   r1   r   Úshlexrq   r<   Ú
subprocessÚPopenÚDEVNULLÚPIPEÚSTDOUTÚOSErrorr	   Ú	threadingÚEventÚThreadr   ÚtimeÚ	monotonicÚis_aliveÚis_setrX   rY   ÚpollrZ   rj   ÚcloseÚdecodeÚ
returncode)rÔ   rå   ræ   rß   rç   ré   rê   r   ÚargsÚexcrô   ÚdrainerÚdeadlinerg   rj   rò   r¯   ró   s     `            @@@r-   Ú_run_rg_nativezSearchMixin._run_rg_nativeD  s  û€ ÷ 	VÜ�d—h‘h  tÓ,Ò8°·±ˆÜ�{‰{˜3Ÿ8™8 D›>Ó*ˆð	CÜ×#Ñ#Ø˜#¡=°·±·±Ó#>Äj×FXÑFXÜ!—‘ÁL¬z×/@Ò/@ÔV`×VhÑVhØ"&ô(ˆDð  ˆÜ—/‘/Ó#ˆ÷	ð 	ô ×"Ñ"¨&¸Ô>ˆØ�‰ŒÜ—>‘>Ó# gÑ-ˆØ#'ˆ	ØØ�L‰L˜ÔØ×#Ñ#Ô%¨¯©Ô)9ØÜ×,Ñ,Ô.Ø�	ØÜ�~‰~Ó (Ò*Ø�	Øð ð �9‰9‹;ÐÙ% dÔ+Ø�	‰	ŒØ�‰ŒØ�‰×ÑÔØ—‘˜%“×'Ñ'¨¸	Ð'ÓBˆØ˜ÒÜ ¨Ð3NÈwÈiÐWYÐ1ZÑ(ZÐfiÔjÐjØ˜ÒÜ ¨Ð1JÑ(JÐVYÔZÐZô  F¸7¿>¹>Ô;K°aÔaÐaÐQU×Q`ÑQ`ÔaÐaøôS ò 	CÜ ¨$¨s¨e¨ÀÔBÕBûð	Cús   ÁA2I É	J É&I;É5J É;J Tre   )rç   Ú	native_okÚshell_prefixÚwordsr  r  c                ó²   — |r%| j                  «       r| j                  ||||¬«      S |rdnd}| j                  |› dj                  |«      › |› d|› �|¬«      S )aD  Run an rg command (shell-quoted words) and keep the first ``fetch_limit``
        lines: natively on a local POSIX host, else through the backend shell as
        ``<prefix><words> | head -n N``. ``native_ok=False`` keeps a form the native
 lane cannot express (the multi-root ``cd`` prefix); ``shell_prefix`` is shell-only.)rç   re   z 2>/dev/nullrë   z | head -n rÞ   )Ú_native_read_enabledr  rÏ   r<   )rÔ   r  ræ   rß   rç   r  r  rí   s           r-   Ú_run_rg_boundedzSearchMixin._run_rg_boundedƒ  sf   € ñ ˜×2Ñ2Ô4Ø×&Ñ& u¨k¸7ÐQ]Ð&Ó^Ð^Ù#‘¨ˆØ�z‰z˜\˜N¨3¯8©8°E«?Ð*;¸F¸8À;È{ÈmÐ\ÐfmˆzÓnÐnrA   c                 ó¼   — t        j                  d|«      r|S ddlm} t	        | j
                  |«      r| j                  |«      S d|j                  dd«      z   dz   S )z>Quote an executable without leaking controller path semantics.z[A-Za-z0-9_.-]+r   )r5   ú'z'"'"')r}   Ú	fullmatchr8   r5   r:   r1   Ú_escape_native_tool_argrÓ   )rÔ   rÛ   r5   s      r-   râ   zSearchMixin._quote_executable�  sW   € ä�<‰<Ð*¨JÔ7ØÐÝ=ä�d—h‘hÐ 0Ô1Ø×/Ñ/°
Ó;Ð;Ø�Z×'Ñ'¨¨YÓ7Ñ7¸#Ñ=Ð=rA   r   c                 óæ   — t        | dd«      }|�t        |dd«      du rg S ddlm} t        | j                  dd«      xs | j                  }t        |||j                  t        j                  ¬	«      S )
a1  Protected descendants to prune for this search root, if any. Gated on
        ``env.is_local``: ``sys.platform``/``_HOME`` describe the CONTROLLER, but the
        search runs on ``env``'s host. Envs without the flag default to local
        semantics; pruning is a warning-carrying skip, never data loss.r1   NÚis_localTFr   ©Úfile_operationsr   r   )	r9   Útoolsr  r1   r   r.   Ú_HOMEr   r   )rÔ   r   r1   Ú_for   s        r-   Ú_macos_search_exclusionsz$SearchMixin._macos_search_exclusions›  sf   € ô
 �d˜E 4Ó(ˆØˆ?œw s¨J¸Ó=ÀÑFØˆIÝ0Ü�d—h‘h  tÓ,Ò8°·±ˆÜ1°$¸CÀcÇiÁiÔZ]×ZfÑZfÔgÐgrA   c           	      óÀ   — | j                  |«      D �cg c]?  }t        j                  j                  t        j                  j	                  ||«      «      ‘ŒA c}S c c}w )z=Absolute-ish protected paths for find's ``-path ... -prune``.)r!  r   r   r    r<   )rÔ   r   Úitems      r-   Ú_protected_prune_pathsz"SearchMixin._protected_prune_paths§  s@   € àGK×GdÑGdÐeiÓGjÖk¸t”—‘× Ñ ¤§¡§¡¨d°DÓ!9Õ:ÒkÐkùÒks   ”AArB   c                 óð  ‡‡— t        | j                  dd«      xs | j                  Št        |«      Šdt        dt        fˆˆfd„}|D �cg c]
  } ||«      ‘Œ }}t        |«      }t        «       }g }t        ||«      D ]ð  \  }}| j                  |«      D ]×  }	‰r,t        j                  t        j                  ||	«      «      x}
}nyt        j                  j                  t        j                  j                  ||	«      «      }
t        j                  j                  t        j                  j                  |
«      «      }||v s||v rŒ³|j                  |«       |j!                  ||	|
f«       ŒÙ Œò |S c c}w )z|Unique ``(root, relative, absolute)`` exclusions across ``roots``, never
        pruning a root the caller chose explicitly.r   Nr(   r   c                 óB  •— ‰rDt        j                  t        j                  | «      r| «      S t        j                  ‰| «      «      S t        j
                  j                  t        j
                  j                  t        j
                  j                  | «      «      «      S rN   )r?   r    r;   r<   r   r   r=   r>   )r(   r   Úuse_posix_pathss    €€r-   Ú
normalizedzBSearchMixin._effective_macos_search_exclusions.<locals>.normalized±  sh   ø€ ÙÜ ×)Ñ)´)·/±/À$Ô2G¨$ÓgÐgÌYÏ^É^Ð\_ÐaeÓMfÓgÐgÜ—7‘7×#Ñ#¤B§G¡G§O¡O´B·G±G×4DÑ4DÀTÓ4JÓ$KÓLÐLrA   )r9   r1   r   r»   r!   rð   Úzipr!  r?   r    r<   r   r   r=   r>   Úaddr&   )rÔ   rB   r(  r(   Únormalized_rootsÚexplicit_rootsÚseenÚ	effectiveÚnormalized_rootr,   ÚabsoluterP   r   r'  s               @@r-   Ú"_effective_macos_search_exclusionsz.SearchMixin._effective_macos_search_exclusions«  sO  ù€ ô �d—h‘h  tÓ,Ò8°·±ˆÜ& uÓ-ˆð	MœSð 	M¤Sö 	Mð
 :?Ö?°™J tÕ,Ð?ÐÐ?ÜÐ-Ó.ˆÜ‹uˆØˆ	Ü%(¨Ð0@Ó%Aò 
	=Ñ!ˆD�/Ø ×9Ñ9¸$Ó?ò 	=�Ù"Ü%.×%7Ñ%7¼	¿¹ÀÐX`Ó8aÓ%bÐb�H™sä!Ÿw™w×/Ñ/´·±·±¸TÀ8Ó0LÓM�HÜŸ'™'×*Ñ*¬2¯7©7¯?©?¸8Ó+DÓE�CØ˜.Ñ(¨C°4©KØØ—‘˜”Ø× Ñ  $¨°(Ð!;Õ<ñ	=ð
	=ð Ðùò @s   Á
E3Úpathsc                 ó>   — dj                  d„ | D «       «      }d|› d�S )Nú, c              3   óZ   K  — | ]#  }t         j                  j                  |«      –— Œ% y ­wrN   )r   r   Úbasename)rO   r#  s     r-   rQ   z>SearchMixin._macos_protected_search_warning.<locals>.<genexpr>É  s   è ø€ ÒE°tœBŸG™G×,Ñ,¨T×2ÑEùs   ‚)+z[Skipped macOS protected folders during broad search to avoid an unattended privacy prompt: z@. Search a protected folder directly when access is intentional.©r<   )r2  Úskippeds     r-   Ú_macos_protected_search_warningz+SearchMixin._macos_protected_search_warningÇ  s/   € à—)‘)ÑE¸uÔEÓEˆð1Ø18°	ð :>ð>ð 	?rA   Úq_rootsc                 ó>   — dj                  d„ | D «       «      }d|› d�S )u¶   find clause pruning hidden dirs while keeping an explicitly selected dot-named root
        (dir or single file) â€” find echoes each start point as given, so ``! -path`` matches it.re   c              3   ó&   K  — | ]	  }d |› �–— Œ y­w)z	 ! -path N© r¹   s     r-   rQ   z1SearchMixin._hidden_prune_expr.<locals>.<genexpr>Ò  s   è ø€ ÒD°D˜y¨¨Ô/ÑDùs   ‚z\( -type d -name '.*'ú
 \) -pruner7  )r:  Ú
exemptionss     r-   Ú_hidden_prune_exprzSearchMixin._hidden_prune_exprÎ  s'   € ð —W‘WÑD¸GÔDÓDˆ
Ø'¨
 |°;Ð?Ð?rA   Úprotected_pathsc                 óD   ‡ — dj                  ˆ fd„|D «       «      }d|› d�S )zGfind ``\( -path A -o -path B \) -prune`` clause for the protected dirs.z -o c              3   óF   •K  — | ]  }d ‰j                  |«      › �–— Œ y­w)z-path N)Ú_escape_shell_arg)rO   r#  rÔ   s     €r-   rQ   z*SearchMixin._prune_expr.<locals>.<genexpr>×  s$   øè ø€ Ò`È˜f T×%;Ñ%;¸DÓ%AÐ$BÔCÑ`ùs   ƒ!z\( r>  r7  )rÔ   rA  Útermss   `  r-   Ú_prune_exprzSearchMixin._prune_exprÕ  s'   ø€ à—‘Ó`ÐP_Ô`Ó`ˆØ�e�W˜KÐ(Ð(rA   c                 ó®   — t        | j                  |xs d| j                  «      }t        d„ |j	                  dd«      j                  d«      D «       «      S )zNTrue when the search root or any ancestor is dot-named (``~/.hermes/skills``).ú.c              3   óJ   K  — | ]  }|j                  d «      xr |dv–— Œ y­w)rH  )rH  z..N)rt   )rO   Úparts     r-   rQ   z5SearchMixin._root_under_hidden_dir.<locals>.<genexpr>Ý  s&   è ø€ ÒsÈ�4—?‘? 3Ó'ÒC¨D¸Ð,CÓCÑsùs   ‚!#r¸   rË   )r@   r1   r   rW   rÓ   rq   )rÔ   r   r(   s      r-   Ú_root_under_hidden_dirz"SearchMixin._root_under_hidden_dirÚ  sI   € ä/°·±¸$º+À#ÀtÇxÁxÓPˆÜÑsÐPT×P\ÑP\Ð]aÐcfÓPg×PmÑPmÐnqÓPrÔsÓsÐsrA   c           	      ó‚   — g }| j                  |«      D ](  }|j                  d| j                  d|› d�«      g«       Œ* |S )zE``--glob '!<dir>/**'`` pairs excluding protected dirs from an rg run.ú--globú!ú/**)r!  ÚextendrD  )rÔ   r   Úoutr#  s       r-   Ú_rg_exclusion_globszSearchMixin._rg_exclusion_globsß  sL   € àˆØ×1Ñ1°$Ó7ò 	JˆDØ�J‰J˜ $×"8Ñ"8¸1¸T¸FÀ#¸Ó"GÐHÕIð	Jàˆ
rA   c                 ó–  — | j                  «       r–t        j                  j                  |«      r|nBt        j                  j	                  t        | j                  dd«      xs | j                  |«      }t        t        j                  j                  |«      rd¬«      S d¬«      S | j                  d| j                  |«      › d�«      S )z„Existence probe; stdout contains "exists" or "not_found" (or the probe's
        ``cwd_error`` when the exec wrapper itself failed).r   NÚexistsÚ	not_found)rj   ztest -e z! && echo exists || echo not_found)r  r   r   r;   r<   r9   r1   r   r	   rT  rÏ   rD  )rÔ   r   Úfulls      r-   Ú_path_exists_probezSearchMixin._path_exists_probeæ  s˜   € ð ×$Ñ$Ô&ÜŸ7™7Ÿ=™=¨Ô.‘4´B·G±G·L±LÄÈÏÉÐSXÐZ^ÓA_ÒAkÐcg×ckÑckÐmqÓ4rˆDÜ ´B·G±G·N±NÀ4Ô4H¨ÔZÐZÈkÔZÐZØ�z‰z˜H T×%;Ñ%;¸DÓ%AÐ$BÐBcÐdÓeÐerA   r…   rõ   Ú	file_globr˜   r™   r—   rš   Úorderc
           	      ód   — |dk(  r| j                  |||||	«      S | j                  |||||||«      S )Nrž   )Ú_search_filesÚ_search_content)
rÔ   r…   r   rõ   rX  r˜   r™   r—   rš   rY  s
             r-   Ú_dispatch_searchzSearchMixin._dispatch_searchî  sC   € ð �WÒØ×%Ñ% g¨t°U¸FÀEÓJÐJØ×#Ñ# G¨T°9¸eÀVÈ[ÐZaÓbÐbrA   c                 ó‚  — t         j                  j                  |«      xs d}t         j                  j                  |«      }d|› �g}| j	                  d| j                  |«      › d�«      }d|j                  v �r$|�r!| j	                  d| j                  |«      › d�«      }|j                  dk(  rî|j                  j                  «       rÔ|j                  «       }|j                  j                  «       j                  d	«      D �cg c]j  }|rf||j                  «       v s4|j                  «       |v s"|j                  «       j                  |d
d «      r t         j                  j                  ||«      ‘Œl }	}|	r&|j                  ddj                  |	d
d «      z   «       t        dj                  |«      d¬«      S c c}w )zFError result for a missing search root, with nearby-entry suggestions.rH  zPath not found: ztest -d z && echo yes || echo norÁ   zls -1 z 2>/dev/null | head -20r   rn   Nr£   zSimilar paths: r4  é   z. r�   )r   r   r+   r6  rÏ   rD  rj   rg   rr   Úlowerrq   rt   r<   r&   r   )
rÔ   r   ÚparentÚbasename_queryÚ
hint_partsÚparent_checkÚ	ls_resultÚlqÚerÙ   s
             r-   Ú_path_not_found_resultz"SearchMixin._path_not_found_resultõ  sˆ  € ä—‘—‘ Ó&Ò-¨#ˆÜŸ™×)Ñ)¨$Ó/ˆØ(¨¨Ð/Ð0ˆ
Ø—z‘z H¨T×-CÑ-CÀFÓ-KÐ,LÐLcÐ"dÓeˆØ�L×'Ñ'Ò'ªNØŸ
™
 V¨D×,BÑ,BÀ6Ó,JÐ+KÐKbÐ#cÓdˆIØ×"Ñ" aÒ'¨I×,<Ñ,<×,BÑ,BÔ,DØ#×)Ñ)Ó+�à5>×5EÑ5E×5KÑ5KÓ5M×5SÑ5SÐTXÓ5YöcØ01Ù˜b A§G¡G£I™o°·±³¸b±ÀAÇGÁGÃI×DXÑDXÐY[Ð\^Ð]^ÐY_ÔD`ô —G‘G—L‘L ¨Õ+ðc�
ð cñ Ø×%Ñ%Ð&7¸$¿)¹)ÀJÈrÐPQÀNÓ:SÑ&SÔTÜ $§)¡)¨JÓ"7ÀQÔGÐGùòcs   ÄA/F<c
           
      ó^  — d|v r>|j                  d«      D �
cg c]#  }
|
j                  «       sŒ|
j                  «       ‘Œ% }}
n|j                  «       }t        |«      dk  ryg g }}|D ]C  }| j                  |«      }d| j	                  |«      j
                  v r|n|j                  |«       ŒE |sy|dk(  r| j                  |||||	«      }�nt        «       }|D ]Ö  }| j                  |||||||«      }|j                  r|c S |j                  j                  |j                  «       |j                  j                  |j                  «       |j                  j                  |j                  «       |xj                   |j                   z  c_        |j"                  xs |j"                  |_        ŒØ |j                  d| |_        |j                  d| |_        dt        |«      › dt        |«      › d�}|r=|d	d
j%                  |dd «      z   z  }t        |«      dkD  r|dt        |«      dz
  › d�z  }|g}|j                  sH| j'                  |«      D ���cg c]  \  }}}|‘Œ
 }}}}|r |j                  | j)                  |«      «       dj%                  |«      |_        |S c c}
w c c}}}w )a0  Recover a not-found ``path`` that is really several paths in one string.
        Commas explicitly delimit paths (internal spaces preserved); without commas
        split on whitespace. Search every existing part, merge, and note skipped
        parts. None when it doesn't look like a multi-path string.ú,rœ   NrT  rž   zpath contained z entries; searched z that existz; skipped missing: r4  r£   ú (+ú more)rë   )rq   rr   r¨   Ú_expand_pathrW  rj   r&   r[  r   r\  r‹   r§   rP  rž   r¢   rS   r‘   rŸ   r<   r1  r9  r’   )rÔ   r…   r   rõ   rX  r˜   r™   r—   rš   rY  rJ  r%   ÚexistingÚmissingÚpÚexpandedÚmergedr(   ri   ÚnoteÚwarning_partsÚ_rÚ_relr0  rA  s                            r-   Ú_try_multi_path_searchz"SearchMixin._try_multi_path_search  s  € ð �$‰;Ø.2¯j©j¸«oÖN dÀÇÁÅ�T—Z‘Z•\ÐNˆEÑNà—J‘J“LˆEÜˆu‹:˜Š>ØØ �'ˆØò 	mˆAØ×(Ñ(¨Ó+ˆHØ! T×%<Ñ%<¸XÓ%F×%MÑ%MÑM‰XÐSZ×bÑbÐckÕlð	mñ ØØ�WÒð ×'Ñ'¨°¸5À&È%ÓPŠFä!“^ˆFØ ò E�Ø×*Ñ*¨7°D¸)ÀUÈFÐT_ÐahÓi�Ø—9’9Ø’JØ—‘×%Ñ% c§k¡kÔ2Ø—‘×#Ñ# C§I¡IÔ.Ø—‘×$Ñ$ S§Z¡ZÔ0Ø×"Ò" c§o¡oÑ5Õ"Ø#)×#3Ñ#3Ò#D°s·}±}�Õ ðEð $Ÿ^™^¨F¨UÐ3ˆFŒNØ!Ÿ<™<¨¨Ð/ˆFŒLØ ¤ U£ Ð,?ÄÀHÃ¸ÈkÐZˆÙØÐ)¨D¯I©I°g¸b¸q°kÓ,BÑBÑBˆDÜ�7‹|˜aÒØ˜#œc '›l¨QÑ.Ð/¨vÐ6Ñ6�Ø˜ˆØ�|Š|ØBF×BiÑBiÐjrÓBs×tÐtÑ,>¨B°°hšxÐtˆOÒtÙØ×$Ñ$ T×%IÑ%IÈ/Ó%ZÔ[ØŸ™ -Ó0ˆŒØˆùòO OùôF us   ˜J#®J#ÉJ(c                 ó®   — g }t        t        «      D ]1  }dD ]*  }|j                  d| j                  d|› |› d�«      f«       Œ, Œ3 dj	                  |«      S )u  rg globs pruning known heavyweight recursive subtrees. Both forms are
        needed: globs are relative to each rg root, so ``**/name/**`` alone misses an
        explicitly selected ``name/`` root. Names come from the shared scan policy â€”
        no second search-only list.)re   ú**/rM  rN  rO  rë   )rF   r   rP  rD  r<   )rÔ   Úglobsr+   Úprefixs       r-   Ú_search_prune_glob_argsz#SearchMixin._search_prune_glob_args8  sk   € ð
 ˆÜÔ4Ó5ò 	[ˆGØ%ò [�Ø—‘˜h¨×(>Ñ(>ÀÀ6À(È7È)ÐSVÐ?WÓ(XÐYÕZñ[ð	[ð �x‰x˜‹ÐrA   ))z-iuv   0 exact matches, but {total} case-insensitive match(es) in {n} file(s): {paths} â€” the pattern's casing may be wrong.)z--hidden --no-ignoreu�   0 matches in visible files, but {total} match(es) in {n} hidden or gitignored file(s): {paths} â€” these are excluded by default.)ú-Fu­   0 regex matches, but {total} literal match(es) in {n} file(s): {paths} â€” the pattern contains regex metacharacters that likely need escaping (or pass a simpler substring).c           	      óX  — | j                  d«      }|sy| j                  |«      }t        t        j                  d|«      «      }|rd| j                  |«      › �nd}| j                  D �]>  \  }}	|dk(  r|sŒ|j                  d«      r|› d| j                  «       › �}
n|}
||d	|
| j                  |«      | j                  |«      g}| j                  |d
d¬«      }dg }}|j                  xs dj                  «       j                  «       D ]G  }|j                  d«      \  }}}|j                  «       sŒ)|t!        |«      z  }|j#                  |«       ŒI |dkD  sŒòt%        |«      dz
  }dj'                  |dd «      |dkD  rd|› d�ndz   }|	j)                  |t%        |«      |¬«      c S  y)zæSteering hint for a 0-match content search, or None: a bare zero gives the
        model nothing to act on, so run cheap count-only rg probes (case-insensitive,
        hidden/ignored, fixed-string) and report the first that hits.rÀ   Nz[.\[\](){}?*+^$\\|]z --glob re   r}  z--hiddenrë   z--count-matchesé2   é   rÞ   r   r¡   r_  r4  rk  rl  )r³   r°   r2  )rÚ   râ   r‡   r}   r‰   rD  Ú_ZERO_MATCH_PROBESrt   r|  r  r  rj   rr   rÐ   Ú
rpartitionÚisdigitr€   r&   r¨   r<   Úformat)rÔ   r…   r   rX  Úrg_executablerÀ   Úhas_metaÚ	glob_exprÚflagsÚtemplateÚglob_expr_probeÚprobe_wordsÚprober³   Úper_filery   rp  Ú_sepr°   Úextrar2  s                        r-   Ú_zero_match_probezSearchMixin._zero_match_probeP  sÂ  € ð ×-Ñ-¨dÓ3ˆÙØØ×#Ñ# MÓ2ˆÜœŸ	™	Ð"8¸'ÓBÓCˆÙFO�h˜t×5Ñ5°iÓ@ÐAÑBÐUWˆ	Ø#×6Ñ6ó 	R‰OˆE�8Ø˜Š}¡XØð ×Ñ 
Ô+Ø%. K¨q°×1MÑ1MÓ1OÐ0PÐ"Q‘à"+�Ø˜uÐ&7¸Ø×1Ñ1°'Ó:¸D×<XÑ<XÐY]Ó<^ð`ˆKà×(Ñ(¨°bÀ"Ð(ÓEˆEØ �8ˆEØŸ™Ò+¨×2Ñ2Ó4×?Ñ?ÓAò '�Ø!Ÿ_™_¨SÓ1‘
��4˜Ø—9‘9•;ØœS ›V‘O�EØ—O‘O AÕ&ð	'ð
 �q‹yÜ˜H›¨Ñ)�ØŸ	™	 (¨2¨A ,Ó/È%ÐRSÊ)°S¸¸¸vÑ3FÐY[Ñ\�Ø—‘¨U´c¸(³mÈ5�ÓQÒQð+	Rð, rA   c                 ó:  ‡ ‡
‡— ddl m}mŠ
mŠ t	        ‰ j
                  |«      sydt        dt        fˆ
ˆˆ fd„}ddlm}  ||«      } ||j                  «      }t        j                  j                  |«      d   }|r|t        j                  z   n,t        j                  j                  t        j                  «      }|t        j                  j                  |«      k(  ry	 t        j                  j!                  ||g«      }	||k(  xs |	|k(  S # t"        $ r Y yw xY w)	z—Whether a no-rg LOCAL root (filesystem root, $HOME or an ancestor of it) is
        unsafe for recursive find. Controller paths never classify remotes.r   r4   FÚvaluer   c                 ót  •— ‰r ‰| «      j                  dd«      } t        j                  j                  | «      sCt        j                  j	                  t        ‰j                  dd «      xs ‰j                  | «      } t        j                  j                  t        j                  j                  | «      «      S )Nr¸   rË   r   )
rÓ   r   r   r;   r<   r9   r1   r   r=   Úrealpath)r’  r6   r7   rÔ   s    €€€r-   r(  z;SearchMixin._is_broad_local_search_root.<locals>.normalizedz  s~   ø€ ÙÙ-¨eÓ4×<Ñ<¸TÀ3ÓG�Ü—7‘7—=‘= Ô'ÜŸ™Ÿ™¤W¨T¯X©X°u¸dÓ%CÒ%OÀtÇxÁxÐQVÓW�ô
 —7‘7×#Ñ#¤B§G¡G×$4Ñ$4°UÓ$;Ó<Ð<rA   r  T)r8   r5   r6   r7   r:   r1   r!   r  r  r  r   r   Ú
splitdriveÚsepr>   r=   Ú
commonpathr$   )rÔ   r   r5   r(  r   r(   r   ÚdriveÚanchorÚcommonr6   r7   s   `         @@r-   Ú_is_broad_local_search_rootz'SearchMixin._is_broad_local_search_rootr  sé   ú€ ÷ 	bÑaä˜$Ÿ(™(Ð$4Ô5Øð		=œcð 		=¤c÷ 		=õ 	1Ù˜$ÓˆÙ˜#Ÿ)™)Ó$ˆÜ—‘×"Ñ" 4Ó(¨Ñ+ˆÙ#(�œŸ™’¬b¯g©g¯o©o¼b¿f¹fÓ.EˆØ”2—7‘7×#Ñ# FÓ+Ò+Øð	Ü—W‘W×'Ñ'¨¨t¨Ó5ˆFð �t‰|Ò-˜v¨™~Ð-øô ò 	Ùð	ús   Ã!!D Ä	DÄDc                 ó  ‡ — |j                  d«      sd|vr|n|j                  d«      d   }t        |t        «      r|gn|}|st	        d¬«      S ‰ j                  d«      r˜‰ j                  d«      xs d}|dk(  r‰ j                  |«      }	|	rt	        |	¬«      S t        ‰ j                  |‰ j                  «      }
t        |
«      st	        t        ¬«      S 	 ‰ j                  ||||||¬«      t        |
«       S t        ˆ fd	„|D «       «      rt	        d
¬«      S ‰ j                  d«      st	        d¬«      S |D �cg c]  }|j                  d«      rd|› �n|‘Œ }}|D �cg c]  }‰ j!                  |«      ‘Œ }}d‰ j#                  |«      › d�}‰ j%                  |«      D ���cg c]  \  }}}|‘Œ
 }}}}|rd‰ j'                  |«      › d�nd}||z   dz   }ddj)                  |«      › |› |› d‰ j!                  |«      › �}|dk(  rd|z   d|› �z   }nd|z   d|› �z   }t        ‰ j                  |‰ j                  «      }
t        |
«      st	        t        ¬«      S 	 ‰ j+                  |d¬«      }t        |
«       t-        |«      \  }}g }|j/                  «       D ]u  }|dk(  rZ|j                  dd«      }t1        |«      dk7  s$|d   j3                  ddd«      j5                  «       sŒM|j7                  |d   «       Œb|sŒe|j7                  |«       Œw |j8                  dk(  xr t1        |«      |k\  }|j8                  dvr|s|dk(  rt	        d¬«      S t	        d ¬«      S dd!lm}m}m }  |r+t        ‰ j                  |«      r|D �!cg c]
  }! | |!«      ‘Œ }}!t	        ||||z    t1        |«      t1        |«      ||z   kD  xs tC        |«      |¬"«      S # t        |
«       w xY wc c}w c c}w c c}}}w # t        |
«       w xY wc c}!w )#zÛSearch for files by name (glob-like) across one or more roots: rg --files,
        else a bounded find. ``order``: "discovery" (fast, bounded) or "modified"
        (exact global newest-first; needs rg 14+ or GNU find).ry  rË   éÿÿÿÿz8File search requires at least one search root in 'path'.rŽ   rÀ   Úmodified©r…  c              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrN   )r›  ©rO   r(   rÔ   s     €r-   rQ   z,SearchMixin._search_files.<locals>.<genexpr>±  s   øè ø€ ÒH¸$ˆt×/Ñ/°×5ÑHùó   ƒz›Broad local file search without ripgrep is disabled because find cannot keep this traversal safely bounded. Install ripgrep or search a narrower directory.ÚfindzƒFile search requires 'rg' (ripgrep) or 'find'. Install ripgrep for best results: https://github.com/BurntSushi/ripgrep#installationÚ-ú./rë   z -ore   r|   zfind -H z -type f ! -name '.*' -name úset -o pipefail; z5 -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -n z -print 2>/dev/null | head -n é<   rÞ   rœ   r   rH  é�   >   r   rd   zsExact modification-time order requires GNU find with -printf support; install ripgrep 14+ or use order='discovery'.z8File search failed while running bounded find traversal.r4   ©rž   r‘   rŸ   r    )"rt   rq   r:   r!   r   rÌ   rÚ   rä   rJ   r1   r   r]   Ú_ADMISSION_INTERRUPTED_ERRORÚ_search_files_rgra   rW   rD  r@  r1  rF  r<   rÏ   rk   rÐ   r¨   rÓ   rƒ  r&   rg   r8   r5   r6   r7   r‡   )"rÔ   r…   r   r˜   r™   rY  Úsearch_patternrB   r…  Úcapability_errorrK   r(   Ú
find_rootsr:  Úhidden_pruneru  rv  r0  rA  Úprotected_pruneræ   Úbaser¾   rb   rj   r    Ú	raw_filesry   r%   Úbounded_sigpiper5   r6   r7   Ú	file_paths"   `                                 r-   r[  zSearchMixin._search_files’  sD  ø€ ð
 *1×);Ñ);¸EÔ)BÀsÐRYÑGY™Ø—‘˜sÓ# BÑ'ð 	ä$ T¬3Ô/�‘°TˆÙÜÐ&`ÔaÐað
 ×Ñ˜TÔ"Ø ×1Ñ1°$Ó7Ò?¸4ˆMØ˜
Ò"Ø#'×#EÑ#EÀmÓ#TÐ Ù#Ü'Ð.>Ô?Ð?Ü-¨d¯h©h¸¸t¿x¹xÓHˆDÜ1°$Ô7Ü#Ô*FÔGÐGð5Ø×,Ñ,¨^¸TÀ5È&ÐRWØ;Hð -ó Jô /¨tÕ4ô ÓHÀ%ÔHÔHÜð:ô<ð <ð × Ñ  Ô(ÜðKôLð Lð QVÖVÈ T§_¡_°SÔ%9˜˜4˜&‘k¸tÑCÐVˆ
ÐVØ<FÖG°D�4×)Ñ)¨$Õ/ÐGˆÐGØ˜4×2Ñ2°7Ó;Ð<¸CÐ@ˆØ>B×>eÑ>eÐfkÓ>l×mÐmÑ(:¨¨D°(š8ÐmˆÒmÙHW˜A˜d×.Ñ.¨Ó?Ð@ÀÑDÐ]_ˆØ˜u‘n qÑ(ˆð ˜3Ÿ8™8 GÓ,Ð-¨oÐ->¸|¸nð M&Ø&*×&<Ñ&<¸^Ó&LÐ%MðOˆà�JÒØ%¨Ñ,Ð1gÐhsÐgtÐ/uÑu‰Cà%¨Ñ,Ð1OÐP[È}Ð/]Ñ]ˆCä)¨$¯(©(°E¸4¿8¹8ÓDˆÜ-¨dÔ3ÜÔ&BÔCÐCð	1Ø—Z‘Z ¨R�ZÓ0ˆFä*¨4Ô0Ü7¸Ó?Ñˆ�ð
  "ˆ	Ø×%Ñ%Ó'ò 	'ˆDØ˜
Ò"ØŸ
™
 3¨Ó*�Ü�u“: ’?¨%°©(×*:Ñ*:¸3ÀÀAÓ*F×*NÑ*NÔ*PØØ× Ñ   q¡Õ*ÚØ× Ñ  Õ&ð	'ð !×*Ñ*¨cÑ1ÒS´c¸)³nÈÑ6SˆØ×Ñ 8Ñ+±OØ˜
Ò"Ü#ðUôWð Wô  Ð&`ÔaÐaçaÑaÙœ: d§h¡hÐ0@ÔAØKTÖU¸iÑ.¨yÕ9ÐUˆIÐUÜØ˜F 6¨E¡>Ð2ÄÀIÃÜ˜)“n v°¡~Ñ5ÒK¼¸lÓ9KÐZfôhð 	høôM /¨tÕ4üò$ WùÚGùämøô. +¨4Õ0üò2 Vs0   ÃO Ä:OÅO Æ#O%ÉO, Î O<ÏOÏ,O9Nr…  c                 óF  ‡ — d|vr|j                  d«      sd|› �n|}t        |t        «      r|gn|}||z   dz   }	‰ j                  |«      }
d}|}t	        |«      dkD  rù|
r÷t        |«      rìt        ‰ j                  dd«      xs ‰ j                  }|D �cg c]B  }t        j                  t        j                  |«      r|nt        j                  ||«      «      ‘ŒD }}t        j                  |«      }|D �cg c]  }t        j                  ||«      ‘Œ }}|
D ���cg c]2  \  }}}d‰ j                  dt        j                  ||«      › d�«      › �‘Œ4 }}}}n-|
D ���cg c]  \  }}}d‰ j                  d|› d�«      › �‘Œ  }}}}d	j                  t         j#                  |«      «      }|rd	|› �nd
}|xs ‰ j%                  d«      }|st'        d¬«      S |dk(  r‰ j)                  |«      }|rt'        |¬«      S ‰ j+                  |«      }|dk(  rdnd
}d	j                  ˆ fd„|D «       «      }|rd‰ j                  |«      › d�nd
}|› d|› d‰ j                  |«      › |› d|› �}‰ j-                  |g|	d| d|› �¬«      }t/        |«      \  }} |j1                  «       D �!cg c]  }!|!sŒ|!‘Œ	 }"}!|rM|"D �!cg c]B  }!t        j                  |!«      r|!n(t        j                  t        j                  ||!«      «      ‘ŒD }"}!|j2                  dk(  xr t	        |"«      |	k\  }#|j2                  dvr|#s|dk(  rt'        d¬«      S t'        d¬«      S t'        |"|||z    t	        |"«      t	        |"«      ||z   kD  xs t5        | «      | ¬«      S c c}w c c}w c c}}}w c c}}}w c c}!w c c}!w )zÜFile-name search via ``rg --files`` (respects .gitignore, skips hidden dirs,
        parallel walk). Discovery order stays bounded and fast; exact modification-time
        ordering is explicit because it scans globally.rË   Ú*r|   Nr   z--glob rN  rO  rë   re   rÀ   z"File search requires ripgrep (rg).rŽ   rž  z --sortr=modifiedc              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrN   )r  r¡  s     €r-   rQ   z/SearchMixin._search_files_rg.<locals>.<genexpr>  s   øè ø€ ÒZÀD˜T×9Ñ9¸$×?ÑZùr¢  zcd z && z --filesz -g z -- r§  r¦  )rß   r  r  r¨  >   r   r|   rd   zhExact modification-time order failed; ripgrep 14+ is required. Upgrade ripgrep or use order='discovery'.z)File search failed while running ripgrep.r©  )rt   r:   r!   r1  r¨   r»   r9   r1   r   r?   r    r;   r<   r—  ÚrelpathrD  ÚdictÚfromkeysrÚ   r   rä   râ   r  rk   rÐ   rg   r‡   )$rÔ   r…   r   r˜   r™   rY  r…  Úglob_patternrB   ræ   Úeffective_exclusionsÚscoped_commonÚcommand_rootsr   r(   Úabsolute_rootsru  rv  r0  Úexclusion_termsr,   Ú_absÚexclusion_globsÚexclusion_argsr­  rÀ   Úsort_argÚ	root_argsÚ	cd_prefixÚrg_cmdrb   rj   r    ÚfÚ	all_filesr³  s$   `                                   r-   r«  zSearchMixin._search_files_rg÷  s  ø€ ð *-°GÑ);ÀG×DVÑDVÐWZÔD[˜˜7˜)‘}ÐbiˆÜ$ T¬3Ô/�‘°TˆØ˜f‘n qÑ(ˆØ#×FÑFÀuÓMÐØˆØˆÜˆu‹:˜Š>Ñ2´|ÀEÔ7Jô ˜$Ÿ(™( E¨4Ó0Ò<°D·H±HˆCð "ö#àô ×"Ñ"¬9¯?©?¸4Ô+@¡4ÄiÇnÁnÐUXÐZ^ÓF_Õ`ð#ˆNð #ô &×0Ñ0°Ó@ˆMØP^Ö_ÈœY×.Ñ.¨t°]ÕCÐ_ˆMÐ_ð +?÷@ð @á&�B˜˜hð ˜$×0Ñ0°1´Y×5FÑ5FÀxÐQ^Ó5_Ð4`Ð`cÐ1dÓeÐfÒgð@ˆOó @ð +?÷@ð @á&�B˜ $ð ˜$×0Ñ0°1°X°J¸cÐ1BÓCÐDÒEð@ˆOò @ð Ÿ(™(¤4§=¡=°Ó#AÓBˆÙ2A˜1˜_Ð-Ñ.ÀrˆØ%ÒD¨×)>Ñ)>¸tÓ)DˆÙÜÐ&JÔKÐKØ�JÒØ#×AÑAÀ-ÓPÐÙÜ#Ð*:Ô;Ð;Ø×#Ñ# MÓ2ˆØ*/°:Ò*=Ñ&À2ˆØ—H‘HÓZÈMÔZÓZˆ	ÙIV�c˜$×0Ñ0°Ó?Ð@ÀÑEÐ\^ˆ	à�D˜  
¨$¨t×/EÑ/EÀlÓ/SÐ.TØ#Ð$ D¨¨ð5ˆà×%Ñ% v h°ÀRÐWdÐSdØ5FÀyÀkÐ3Rð &ó Tˆä7¸Ó?Ñˆ�Ø &× 1Ñ 1Ó 3Ö9˜1²q’QÐ9ˆ	Ð9Ùð #ö$àô —_‘_ QÔ'‘¬Y×-?Ñ-?Ä	ÇÁÈ}Ð^_Ó@`Ó-aÑað$ˆIð $ð !×*Ñ*¨cÑ1ÒS´c¸)³nÈÑ6SˆØ×Ñ ;Ñ.±Ø˜
Ò"Ü#ðJôLð Lô  Ð&QÔRÐRÜØ˜F 6¨E¡>Ð2ÄÀIÃÜ˜)“n v°¡~Ñ5ÒK¼¸lÓ9KÐZfôhð 	hùòW#ùò `ùô@ùô@ùò, :ùò$s,   ÂANÃ6NÄ7NÅ#NÊNÊ&NÊ2ANc                 ó   — | j                  d«      }|r-| j                  |||||||| j                  d«      xs d¬«      }	n5| j                  d«      r| j                  |||||||«      }	nt	        d¬«      S |	j
                  sm|	j                  dk(  r^|	j                  sR|	j                  sF|	j                  s:	 | j                  |||«      }
|
r$|	j                  s|
n|	j                  › d|
› �|	_        |r|	S t        |	|«      S # t        $ r d}
Y ŒCw xY w)	zBContent search: rg, else grep; attaches zero-match steering hints.rÀ   rŸ  ÚgrepzqContent search requires ripgrep (rg) or grep. Install ripgrep: https://github.com/BurntSushi/ripgrep#installationrŽ   r   Nrë   )rÌ   Ú_search_with_rgrÚ   Ú_search_with_grepr   r‹   r‘   r§   rž   r¢   r�  Ú	Exceptionr’   r“   )rÔ   r…   r   rX  r˜   r™   r—   rš   Úused_rgrb   Úhints              r-   r\  zSearchMixin._search_content6  s(  € ð ×#Ñ# DÓ)ˆÙØ×)Ñ)¨'°4¸ÀEÈ6ÐS^Ð`gØ8<×8MÑ8MÈdÓ8SÒ8[ÐW[ð *ó ]‰Fà×Ñ˜vÔ&Ø×+Ñ+¨G°T¸9ÀeÈVÐU`ÐbiÓj‰Fäð\ô]ð ]ð —’ ×!3Ñ!3°qÒ!8ØŸš¨v¯|ª|ÀFÇMÂMðØ×-Ñ-¨g°t¸YÓG�ñ Ø-3¯^ª^¡ÀFÇNÁNÐCSÐSTÐUYÐTZÐA[�”ñ ØˆMÜ8¸ÀÓIÐIøô ò Ø’ðús   Â6C? Ã?DÄDÚ	cmd_partsr’   Úline_capc                 óø   — ||z   |dkD  rdndz   }|rC|dddt        |«      gz   }	|dvr|	g d¢z  }	| j                  dd	j                  |	«      z   d
¬«      }
n| j                  ||d
dd¬«      }
t	        |
|||||¬«      S )a  Run ``cmd_parts | head -n <fetch_limit>`` under pipefail and parse. Extra
        rows report the true total (context mode also emits "--" separators, so
        grab 200 more). pipefail keeps the engine's exit 2 alive across ``| head``
        (a truncating head makes rg exit 0 / grep 141, which the ==2 guard ignores).
        ``line_cap`` appends ``| cut -c1-2000`` for engines without --max-columns
        (grep): bounds giant single-line matches at the pipe layer; skipped for
        files_only/count where lines are paths/counts.r   éÈ   Ú|Úheadz-nr”   )rÕ  Úcutz-c1-2000r¦  rë   r§  rÞ   T)rß   rç   r  ©r’   )r!   rÏ   r<   r  r´   )rÔ   rÑ  r—   r˜   r™   rš   r’   rÒ  ræ   r%   rb   s              r-   Ú_run_search_pipelinez SearchMixin._run_search_pipelineQ  s¡   € ð ˜f‘n¨w¸ª{©ÀÑBˆÙØ  f¨d´C¸Ó4DÐ EÑEˆEØÐ"9Ñ9ØÒ1Ñ1�Ø—Z‘ZÐ 3°c·h±h¸u³oÑ EÈr�ZÓR‰Fà×)Ñ)¨)°[È"Ð[_Ø7Jð *ó LˆFä# F¨K¸ÀÈÐY`ÔaÐarA   c	                 ó   — |xs | j                  d«      }|st        d¬«      S | j                  |«      dddg}	|dvr|	j                  g d¢«       t	        |«      }
|
r|	j                  d	«       |d
kD  r|	j                  dt        |«      g«       |	j                  | j                  |«      «       |r"|	j                  d| j                  |«      g«       |t        v r|	j                  t        |   «       |	j                  | j                  |«      «       |	j                  | j                  |«      «       |
rdnd}| j                  |	|||||¬«      S )zSearch using ripgrep.rÀ   z%Content search requires ripgrep (rg).rŽ   z--line-numberz--no-headingz--with-filenamer”   )z--max-columnsÚ2000z--max-columns-previewr�   r   ú-CrM  ut   Pattern contains \n â€” multiline mode (-U) was enabled automatically so the regex can match across line boundaries.NrØ  )rÚ   r   râ   rP  rŠ   r&   r!   rR  rD  Ú_OUTPUT_MODE_FLAGSr  rÙ  )rÔ   r…   r   rX  r˜   r™   r—   rš   r…  rÑ  Ú	multilineÚml_notes               r-   rÌ  zSearchMixin._search_with_rgf  sR  € ð &ÒD¨×)>Ñ)>¸tÓ)DˆÙÜÐ&MÔNÐNØ×+Ñ+¨MÓ:¸OÈ^Ð]nÐoˆ	ð Ð5Ñ5Ø×ÑÒOÔPä.¨wÓ7ˆ	ÙØ×Ñ˜]Ô+Ø�QŠ;Ø×Ñ˜d¤C¨£LÐ1Ô2Ø×Ñ˜×1Ñ1°$Ó7Ô8ÙØ×Ñ˜h¨×(>Ñ(>¸yÓ(IÐJÔKØÔ,Ñ,Ø×ÑÔ/°Ñ<Ô=Ø×Ñ˜×/Ñ/°Ó8Ô9à×Ñ˜×5Ñ5°dÓ;Ô<ñ ñ=à ð 	ð ×(Ñ(¨°KÀÈÐPWÐahÐ(ÓiÐirA   rÖ  c                 ó&  — t        |«      }|dkD  r|j                  dt        |«      g«       |r"|j                  d| j                  |«      g«       |t        v r|j                  t        |   «       |j                  | j                  |«      «       |S )zQ``head`` + context/include/mode flags + quoted pattern (argument order is fixed).r   rÜ  z	--include)ÚlistrP  r!   rD  rÝ  r&   )rÔ   rÖ  r…   r—   rš   rX  r%   s          r-   Ú	_grep_cmdzSearchMixin._grep_cmd‰  s   € ô �T“
ˆØ�QŠ;Ø�L‰L˜$¤ G£Ð-Ô.ÙØ�L‰L˜+ t×'=Ñ'=¸iÓ'HÐIÔJØÔ,Ñ,Ø�L‰LÔ+¨KÑ8Ô9Ø�‰�T×+Ñ+¨GÓ4Ô5ØˆrA   c           
      óî  — | j                  |«      }|s| j                  |«      r| j                  ||||||||«      S | j                  g d¢||||«      }	|j	                  d«      xs t        t        j                  d|«      «      }
|
r| j                  |«      }n5|j	                  d«      r|dd n|}d}|dvr|d	| j                  |«      › �z  }|	j                  |«       | j                  |	||||d
¬«      S )zFallback search using grep.)rË  z-rnHEz--exclude-dir='.*')rË   z\\r·   r¥  rœ   Nz"$PWD">   re   rH  rË   T©rÒ  )r$  rK  Ú_search_with_grep_prunedrâ  rt   r‡   r}   rv   rD  r&   rÙ  )rÔ   r…   r   rX  r˜   r™   r—   rš   rA  rÑ  r   Úsearch_rootÚrelative_paths                r-   rÍ  zSearchMixin._search_with_grep–  s  € ð
 ×5Ñ5°dÓ;ˆñ ˜d×9Ñ9¸$Ô?Ø×0Ñ0Ø˜˜y¨%°¸ÀgÈó`ð `ð —N‘NÒ#JÈGÐU`ÐbiÐktÓuˆ	ð —o‘o mÓ4Ò`¼¼R¿X¹XÐFXÐZ^Ó=_Ó8`ˆÙØ×0Ñ0°Ó6‰Kà(,¯©¸Ô(=˜D  ™HÀ4ˆMØ"ˆKØ IÑ-Ø  4×#9Ñ#9¸-Ó#HÐ"IÐJÑJ�Ø×Ñ˜Ô%Ø×(Ñ(¨°KÀÈÐPWÐbfÐ(ÓgÐgrA   c	                 óœ  — | j                  ddg|||«      }	| j                  |xs d«      }
dd|
g}|r"|j                  | j                  |«      dg«       |j                  | j	                  |
g«      ddg«       |r"|j                  d| j                  |«      g«       |j                  d	g|	¢d
‘d‘d‘«       | j                  |||||d¬«      S )aL  grep fallback via ``find ... -prune -exec grep {} +``, used when the root needs
        path-scoped pruning (macOS protected dirs) or is itself under a dot-directory
        (#18473: grep's ``--exclude-dir='.*'`` would drop the root). Trade-off: find folds
        grep's exit code, so a hard grep error surfaces as an empty result.rË  z-nHErH  r£  z-Hz-oz-type fz-namez-execz{}ú+z2>/dev/nullTrä  )râ  rD  rP  rF  r@  rÙ  )rÔ   r…   r   rX  r˜   r™   r—   rš   rA  Ú
grep_partsÚq_rootÚ
find_partss               r-   rå  z$SearchMixin._search_with_grep_pruned²  sè   € ð —^‘^ V¨VÐ$4°g¸{ÈGÓTˆ
Ø×'Ñ'¨ª°Ó4ˆð ˜d FÐ+ˆ
ÙØ×Ñ˜t×/Ñ/°Ó@À$ÐGÔHØ×Ñ˜4×2Ñ2°F°8Ó<¸dÀIÐNÔOÙØ×Ñ˜w¨×(>Ñ(>¸yÓ(IÐJÔKØ×Ñ˜7ÐJ ZÐJ°ÐJ°sÐJ¸MÐJÔKØ×(Ñ(¨°[À%ÈÐQXÐcgÐ(ÓhÐhrA   )F)Ú	discovery)rí  N)NFrN   )-Ú__name__rG   rH   Ú__doc__r!   r   rÚ   r}   Úcompilerã   rä   r   r€   r‡   r	   r  r  râ   r!  r$  rE   r1  Ústaticmethodr9  r@  rF  rK  rR  rW  r   r]  rh  rw  r|  r�  r�  r›  r[  r«  r\  rÙ  rÌ  râ  rÍ  rå  r=  rA   r-   r½   r½   ÿ   sÏ  „ ñUð" Cð "¨H°S©Mó "ðH  �R—Z‘Zð	%ó&€Nð¸ð ÀÈÁó ð" -2ñ=b 4¨¡9ð =b¸3ð =bÈð =bØ%)ð=bØ6Có=bð@ .3ÀdØ,.ò
o T¨#¡Yð 
o¸Sð 
oÈ3ð 
oØ&*ð
oØ?Cð
oà&)ð
oà3@ó
oð>¨Cð >°Có >ð
h¨Sð 
h°T¸#±Yó 
hðl¨3ð l°4¸±9ó lð¸¸S¹	ð ÀdÈ5ÐQTÐVYÐ[^ÐQ^ÑK_ÑF`ó ð8 ð?¨t°C©yð ?¸Sò ?ó ð?ð ð@ D¨¡Ið @°#ò @ó ð@ð)¨4°©9ð )¸ó )ð
t¨3ð t°4ó tð
¨ð °°S±	ó ðf sð f¨}ó fð GRñc¨ð c°3ð cÀð cØ$,¨S¡MðcØ:=ðcØGJðcà&)ðcà47ðcà@CðcàVbócðH¨3ð H°<ó Hð( -8ñ0¨cð 0¸ð 0Àcð 0Ø*2°3©-ð0Ø@Cð0ØMPð0à,/ð0à:=ð0ð '*ð0ð =EÀ\Ñ<Ró0ðd	¨ó 	ð	Ðð ¨ð  °Cð  ÀHÈSÁMð  ÐV^Ð_bÑVcó  ðD.°ð .¸ó .ðB $/ñch Sð ch°°d¸3±i±ð chÈð chÐUXð chØ ðchØ3?óchðL SWñ=h¨ð =h°3¸¸c¹±?ð =hÈ3ð =hÐX[ð =hØ #ð=hØBJÈ3Á-ð=hØ[gó=hð~J sð J°#ð JÀ(È3Á-ð JØ"ðJØ,/ðJØ>AðJØLOðJØT`óJð8 RVØ.3ñb¨d°3©ið bÀcð bÐRUð bØ%(ðbØ36ðbØAIÈ#Áðbà'+ðbà8Dóbð. 8<ñ!j sð !j°#ð !jÀ(È3Á-ð !jØ"ð!jØ,/ð!jØ>Að!jØLOð!jà'/°¡}ð!jà@Ló!jðH .2ñ˜d 3™ið °#ð ÀCð ÐRUð Ø% c™]ðØ6:¸3±ióðh¨ð h°Cð hÀHÈSÁMð hØ!$ðhØ.1ðhØ@CðhØNQðhØVbóhð8i°ð i¸3ð iÈ8ÐTWÉ=ð iØ(+ðiØ58ðiØGJðiØUXðià26°s±)ðià@LôirA   r½   rN   )8rï  r   r?   r}   rù   rú   r   r   r  Úpathlibr   Útypingr   r   r   Úagent.search_policyr   r  r   rX   Útools.file_operations_commonr	   r
   r   r"   r!   r.   Ú	ConditionrV   rð   r/   rE   Ú__annotations__r[   r@   rJ   r‡   r]   ra   rª  rð  rh   rk   ru   rz   r€   r„   rˆ   rŠ   r�   r“   r¬   rÝ  r´   r»   r½   r=  rA   r-   ú<module>rø     sï  ðòó 
Û Û 	Û Û Û 
Û Û Ý ß &Ñ &å 6Ý -ß QÑ Qð"Ð ð (,À4ÐcgòØ
ðØ ‘}ðØ3;¸C±=ðØS[Ð\_ÑS`ðà	ˆ#�Yóð: 1˜Y×0Ñ0Ó2Ð Ù;>»5Ð ˜s 5¨¨c°3¨Ñ#7Ñ8Ó @Ø $Ð ð$¨#ð $°Sð $Èð $ÐPSó $ð" Cð °°S±	ð Èð ÐQVÐW\Ð]`ÐbeÐgjÐ]jÑWkÐmpÐWpÑQqó ði¨¨u°S¸#¸s°]Ñ/CÀSÐ/HÑ)Ið iÈdó ið0¨¨u°S¸#¸s°]Ñ/CÀSÐ/HÑ)Ið 0Èdó 0ð1ð ð '˜BŸJ™JÐ'QÓRÐ ð ]ð °u¸SÀ(È3Á-Ð=OÑ7Pó ð �B—J‘JÐRÓSÐ ð6 Cð 6¨E°#°s°(©Oó 6ð(I Sð I¨U°3¸¸S°=Ñ-AÀDÑ-Hó Ið &˜2Ÿ:™:Ð&<Ó=Ð ðM¨ð M°ó Mð`¨8°C©=ð `¸Tó `ð
°lð ÈSð ÐUaó ð" �—‘Ð=Ó>€ð %)°4Ñ8Ð ð AEñ/¨cð /¸#ð /Àsð /Ø"%ð/Ø08¸±ð/ØIUó/ðdW˜˜S™	ð W dó W÷Fiò FirA   