Ë
    ãß²jº,  ã            	       ó´  — d Z ddlZddlmZmZ ddlmZmZmZm	Z	m
Z
 e G d„ d«      «       Ze G d„ d«      «       Ze G d	„ d
«      «       Ze G d„ d«      «       Ze G d„ d«      «       Ze G d„ d«      «       Ze G d„ d«      «       Z ej$                  d«      Z ej$                  d«      Z ej$                  dej*                  «      Z ej$                  dej*                  «      Z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defd„Zd Zdedeee f   fd!„Z!de
e   de fd"„Z"d#Z#d$Z$dZ%d%Z&d&ed'edefd(„Z'e#e$fd)ed*edeeef   fd+„Z(e%e&fd)ed*edeeef   fd,„Z)y)-uH  Result dataclasses and pure text helpers shared by ``tools.file_operations``
and its search/lint mixins. Leaf module (imports nothing from ``tools`` at module
scope) so nothing cycles. The ``to_dict`` output of every class here IS tool
behavior â€” key names, order and omission rules are pinned by tests and read by
the model.
é    N)Ú	dataclassÚfield)ÚAnyÚClassVarÚDictÚListÚOptionalc                   ó   — e Zd ZU dZdZeed<   dZeed<   dZ	eed<   dZ
eed<   d	Zee   ed
<   d	Zee   ed<   dZeed<   dZeed<   d	Zee   ed<   d	Zee   ed<   d	Zee   ed<   d	Zee   ed<    ee¬«      Zee   ed<   d	Zee   ed<   defd„Zy	)Ú
ReadResultzResult from reading a file.Ú Úcontentr   Útotal_linesÚ	file_sizeFÚ	truncatedNÚtruncated_linesÚhintÚ	is_binaryÚis_imageÚbase64_contentÚ	mime_typeÚ
dimensionsÚerror©Údefault_factoryÚsimilar_filesÚ	_snapshotÚreturnc                 ó    — | j                   j                  «       D ��ci c]#  \  }}|j                  d«      rŒ|€Œ|g k7  sŒ!||“Œ% c}}S c c}}w ©NÚ_©Ú__dict__ÚitemsÚ
startswith©ÚselfÚkÚvs      úA/home/ubuntu/.hermes/hermes-agent/tools/file_operations_common.pyÚto_dictzReadResult.to_dict   sE   € Ø!%§¡×!4Ñ!4Ó!6×n™˜˜A¸a¿l¹lÈ3Õ>OÐTUÑTaÐfgÐkmÓfm��1‘ÓnÐnùÓns   žA
¸A
»A
ÁA
)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚstrÚ__annotations__r   Úintr   r   Úboolr   r	   r   r   r   r   r   r   r   r   Úlistr   r   r   ÚtupleÚdictr*   © ó    r)   r   r      sÄ   … á%Ø€GˆSÓØ€K�ÓØ€IˆsÓØ€IˆtÓØ&*€O�X˜d‘^Ó*Ø€Dˆ(�3‰-ÓØ€IˆtÓØ€HˆdÓØ$(€N�H˜S‘MÓ(Ø#€Iˆx˜‰}Ó#Ø $€J�˜‘Ó$Ø€Eˆ8�C‰=ÓÙ$°TÔ:€M�4˜‘9Ó:Ø!%€Iˆx˜‰Ó%ðo˜ô or7   r   c                   ó¼   — e Zd ZU dZdZeed<   dZeed<   dZ	e
e   ed<   dZe
e   ed<   dZe
eeef      ed	<   dZe
e   ed
<   dZe
e   ed<   dZe
e   ed<   defd„Zy)ÚWriteResultzResult from writing a file.r   Úbytes_writtenFÚdirs_createdNÚverifiedÚ_content_sha256ÚlintÚlsp_diagnosticsr   Úwarningr   c                 ó”   — | j                   j                  «       D ��ci c]  \  }}|j                  d«      rŒ|€Œ||“Œ c}}S c c}}w r   r!   r%   s      r)   r*   zWriteResult.to_dict3   s<   € Ø!%§¡×!4Ñ!4Ó!6×b™˜˜A¸a¿l¹lÈ3Õ>OÐTUÑTa��1‘ÓbÐbùÓbs   žA¸A»A)r+   r,   r-   r.   r:   r1   r0   r;   r2   r<   r	   r=   r/   r>   r   r   r?   r   r@   r5   r*   r6   r7   r)   r9   r9   #   sˆ   … á%Ø€M�3ÓØ€L�$Óð  $€Hˆh�t‰nÓ#Ø%)€O�X˜c‘]Ó)Ø%)€Dˆ(�4˜˜S˜‘>Ñ
"Ó)ð &*€O�X˜c‘]Ó)Ø€Eˆ8�C‰=ÓØ!€GˆX�c‰]Ó!ðc˜ô cr7   r9   c                   ó  — e Zd ZU dZdZeed<   dZeed<    e	e
¬«      Zee   ed<    e	e
¬«      Zee   ed<    e	e
¬«      Zee   ed	<   d
Zeeeef      ed<   d
Zee   ed<   d
Zee   ed<   dZeed<   d
Zee   ed<   dZee   ed<   defd„Zy
)ÚPatchResultzResult from patching a file.FÚsuccessr   Údiffr   Úfiles_modifiedÚfiles_createdÚfiles_deletedNr>   r?   r   Ú	no_changeÚnote)rE   rF   rG   rH   r>   r?   r   Ú_DICT_FIELDSr   c                 óÄ   — d| j                   i}| j                  rd|d<   | j                  r| j                  |d<   | j                  D ]  }t	        | |«      }|sŒ|||<   Œ |S )NrD   TrI   rJ   )rD   rI   rJ   rK   Úgetattr)r&   ÚresultÚkeyÚvalues       r)   r*   zPatchResult.to_dictL   si   € Ø"+¨T¯\©\Ð!:ˆØ�>Š>Ø"&ˆF�;ÑØ�9Š9Ø!ŸY™YˆF�6‰NØ×$Ñ$ò 	$ˆCÜ˜D #Ó&ˆEÚØ#��s’ð	$ð ˆr7   )r+   r,   r-   r.   rD   r2   r0   rE   r/   r   r3   rF   r   rG   rH   r>   r	   r   r   r?   r   rI   rJ   rK   r   r4   r5   r*   r6   r7   r)   rC   rC   7   sº   … á&Ø€GˆTÓØ€Dˆ#ƒNÙ %°dÔ ;€N�D˜‘IÓ;Ù$°TÔ:€M�4˜‘9Ó:Ù$°TÔ:€M�4˜‘9Ó:Ø%)€Dˆ(�4˜˜S˜‘>Ñ
"Ó)Ø%)€O�X˜c‘]Ó)Ø€Eˆ8�C‰=Óà€IˆtÓØ€Dˆ(�3‰-Óð%€L�(˜5‘/ó ð

˜ô 
r7   rC   c                   ó>   — e Zd ZU dZeed<   eed<   eed<   dZeed<   y)ÚSearchMatchzA single search match.ÚpathÚline_numberr   g        ÚmtimeN)	r+   r,   r-   r.   r/   r0   r1   rU   Úfloatr6   r7   r)   rR   rR   Y   s   … á Ø
ƒIØÓØƒLØ€Eˆ5Ôr7   rR   c                   ó  — e Zd ZU dZ ee¬«      Zee   e	d<    ee¬«      Z
ee   e	d<    ee¬«      Zeeef   e	d<   dZee	d<   dZee	d	<   d
Zee   e	d<   d
Zee   e	d<   d
Zee   e	d<   dZee   e	d<   dee   fd„Zddedefd„Zy
)ÚSearchResultzResult from searching.r   ÚmatchesÚfilesÚcountsr   Útotal_countFr   NÚlimit_reasonr@   r   é   Ú_DENSIFY_MIN_MATCHESr   c                 ór  — t        | j                  «      | j                  k  ryg }d}| j                  D ]q  }|j                  |k7  r'|j	                  |j                  «       |j                  }|j	                  d|j
                  › d|j                  j                  «       › �«       Œs dj                  |«      S )zÁLossless path-grouped text block: path once, then ``  <line>: <content>``
        rows. Relies on rg/grep emitting a file's hits consecutively. None when
        too few matches to be worth it.Nz  z: Ú
)	ÚlenrY   r_   rS   ÚappendrT   r   ÚrstripÚjoin)r&   ÚlinesÚcurrent_pathÚms       r)   Ú_densify_matcheszSearchResult._densify_matchesr   sž   € ô ˆt�|‰|Ó˜t×8Ñ8Ò8ØØˆØ&*ˆØ—‘ò 	EˆAØ�v‰v˜Ò%Ø—‘˜QŸV™VÔ$Ø Ÿv™v�à�L‰L˜2˜aŸm™m˜_¨B¨q¯y©y×/?Ñ/?Ó/AÐ.BÐCÕDð	Eð �y‰y˜ÓÐr7   Údensifyc                 óÒ  — d| j                   i}| j                  r`|r| j                  «       nd }|�d|d<   ||d<   n?| j                  D �cg c]&  }|j                  |j                  |j
                  dœ‘Œ( c}|d<   | j                  r| j                  |d<   | j                  r| j                  |d<   | j                  r
d	|d
<   d	|d<   dD ]  }t        | |«      }|sŒ|||<   Œ |S c c}w )Nr\   ztpath-grouped: each file path on its own line, followed by indented '<line>: <content>' rows for matches in that fileÚmatches_formatÚmatches_text)rS   Úliner   rY   rZ   r[   Tr   Útotal_count_is_lower_bound)r]   r@   r   )
r\   rY   ri   rS   rT   r   rZ   r[   r   rM   )r&   rj   rN   Údenserh   rO   rP   s          r)   r*   zSearchResult.to_dict‚   sÿ   € Ø%2°D×4DÑ4DÐ$EˆØ�<Š<Ù/6�D×)Ñ)Ô+¸DˆEØÐ ðQð Ð'Ñ(ð */��~Ò&ð \`×[gÑ[gö%ØVW˜QŸV™V¨Q¯]©]ÀqÇyÁyÓQò%��yÑ!ð �:Š:Ø"Ÿj™jˆF�7‰OØ�;Š;Ø#Ÿ{™{ˆF�8ÑØ�>Š>Ø"&ˆF�;ÑØ37ˆFÐ/Ñ0Ø7ò 	$ˆCÜ˜D #Ó&ˆEÚØ#��s’ð	$ð ˆùò%s   Á
+C$)F)r+   r,   r-   r.   r   r3   rY   r   rR   r0   rZ   r/   r5   r[   r   r1   r\   r   r2   r]   r	   r@   r   r_   r   ri   r*   r6   r7   r)   rX   rX   b   sµ   … á Ù!&°tÔ!<€GˆT�+ÑÓ<Ù¨TÔ2€Eˆ4�‰9Ó2Ù"°4Ô8€FˆD��c�‰NÓ8Ø€K�ÓØ€IˆtÓØ"&€L�(˜3‘-Ó&Ø!€GˆX�c‰]Ó!Ø€Eˆ8�C‰=Óð +,Ð˜( 3™-Ó+ð  (¨3¡-ó  ñ ˜tð °ô r7   rX   c                   óV   — e Zd ZU dZdZeed<   dZeed<   dZe	ed<   dZ
e	ed<   d	efd
„Zy)Ú
LintResultzResult from linting a file.TrD   FÚskippedr   ÚoutputÚmessager   c                 ó¬   — | j                   rd| j                  dœS | j                  rdnd| j                  dœ}| j                  r| j                  |d<   |S )Nrs   )Ústatusru   Úokr   )rw   rt   ru   )rs   ru   rD   rt   )r&   rN   s     r)   r*   zLintResult.to_dict§   sH   € Ø�<Š<Ø'°D·L±LÑAÐAØ$(§L¢L™D°gÈÏÉÑUˆØ�<Š<Ø $§¡ˆF�9ÑØˆr7   N)r+   r,   r-   r.   rD   r2   r0   rs   rt   r/   ru   r5   r*   r6   r7   r)   rr   rr   Ÿ   s9   … á%Ø€GˆTÓØ€GˆTÓØ€FˆCÓØ€GˆSÓð˜ô r7   rr   c                   ó<   — e Zd ZU dZdZeed<   dZeed<   dZ	eed<   y)ÚExecuteResultz&Result from executing a shell command.r   Ústdoutr   Ú	exit_codeÚ	cwd_errorN)
r+   r,   r-   r.   r{   r/   r0   r|   r1   r}   r6   r7   r)   rz   rz   °   s%   … á0Ø€FˆCÓØ€IˆsÓð €IˆsÔr7   rz   z!\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)z+'?\x07?__HERMES_FENCE_[A-Za-z0-9]+__\x07?'?z^\s*\d+\|<<<<<<< z^\s*\d+\|>>>>>>> Úformatted_contentr   c                 ó–   — t        t        j                  | «      «      }|r(t        |t        t        j                  | «      «      «      S dS )a  Unresolved git merge-conflict blocks in a ``LINE|CONTENT`` read; 0 when the page has no
    balanced ``<<<<<<< `` / ``>>>>>>> `` pair (a lone marker in prose or a test fixture is not a
    conflict). Reported on read so the model resolves the conflict instead of editing around it.r   )rb   Ú_CONFLICT_OPENÚfindallÚminÚ_CONFLICT_CLOSE)r~   Úopenss     r)   Úcount_conflict_blocksr…   Ç   s@   € ô ”×&Ñ&Ð'8Ó9Ó:€EÙJOŒ3ˆu”cœ/×1Ñ1Ð2CÓDÓEÓFÐVÐUVÐVr7   Útextc                 ó6  — | s| S g }| j                  d¬«      D ]n  }d|v xs d|v }t        j                  dt        j                  d|«      «      j	                  dd«      }|r|j                  d«      dk(  rŒ^|j                  |«       Œp dj                  |«      S )z‡Strip leaked terminal fence wrappers (OSC sequences, fence markers) from
    command output; drops lines that were nothing but wrapper.T)ÚkeependsÚ__HERMES_FENCE_z]r   úz'
	 )Ú
splitlinesÚ_FENCE_MARKER_REÚsubÚ_OSC_SEQUENCE_REÚreplaceÚstriprc   re   )r†   Úcleaned_linesrn   Úhad_terminal_wrapperÚcleaneds        r)   Ú_strip_terminal_fence_leaksr”   Ï   s£   € ñ ØˆØ!€MØ—‘¨�Ó.ò &ˆØ0°DÐ8ÒK¸GÀt¸OÐÜ"×&Ñ& rÔ+;×+?Ñ+?ÀÀDÓ+IÓJ×RÑRÐSYÐ[]Ó^ˆÙ G§M¡M°*Ó$=ÀÒ$CØØ×Ñ˜WÕ%ð&ð �7‰7�=Ó!Ð!r7   Úsamplec                 ó*   — | r| dd nd}d|v ryd|v ryy)a'  Dominant line ending of ``sample`` (``\r\n`` if any CRLF in the first 4KB,
    else ``\n``), or None for empty/single-line content. Preserves a file's
    endings across write_file/patch: bare-LF tool args would otherwise silently
    normalize CRLF files, and patch would produce mixed endings.Ni   r   ú
ra   r6   )r•   Úheads     r)   Ú_detect_line_endingr™   Þ   s*   € ñ
 #ˆ6�%�4‰=¨€DØ��~ØØˆt�|ØØr7   Útargetc                 ó†   — | j                  dd«      j                  dd«      }|dk(  r|S |dk(  r|j                  dd«      S | S )u°   Convert every line ending (CRLF, lone CR, LF) in ``text`` to ``target``.
    Idempotent. Collapses to LF first â€” separate replacements would
    double-convert CRLF â†’ LFLF.r—   ra   ú)r�   )r†   rš   Úlf_normalizeds      r)   Ú_normalize_line_endingsrž   ë   sN   € ð —L‘L ¨Ó.×6Ñ6°t¸TÓB€MØ�‚~ØÐØ�ÒØ×$Ñ$ T¨6Ó2Ð2Ø€Kr7   u   ï»¿c                 óH   — t        | «      r| t        t        «      d dfS | dfS )zvReturn (text-without-leading-BOM, had_bom). Only a leading BOM is
    stripped; mid-content U+FEFF is legitimate data.NTF)Ú_has_bomrb   Ú	_UTF8_BOM©r†   s    r)   Ú
_strip_bomr£   ý   s+   € ô �„~Ø”Cœ	“N�OÐ$ dÐ*Ð*Ø�ˆ;Ðr7   c                 óF   — t        | «      xr | j                  t        «      S )z)True if ``text`` begins with a UTF-8 BOM.)r2   r$   r¡   r¢   s    r)   r    r      s   € ä�‹:Ò4˜$Ÿ/™/¬)Ó4Ð4r7   é   iÐ  é2   rP   Údefaultc                 óH   — 	 t        | «      S # t        t        f$ r |cY S w xY w)z8Best-effort integer coercion for tool pagination inputs.)r1   Ú	TypeErrorÚ
ValueError)rP   r§   s     r)   Ú_coerce_intr«     s*   € ðÜ�5‹zÐøÜ”zÐ"ò ØŠðús   ‚
 �! !ÚoffsetÚlimitc           	      óœ   — ddl m} t        dt        | t        «      «      }t        dt        t        |t        «       |«       «      «      }||fS )zâClamp read_file pagination so invalid values can never reach a sed range
    like ``0,-1p`` (schemas declare bounds, but not every caller enforces them).
    The ``limit`` ceiling is ``tool_output.max_lines`` from config.yaml.r   )Úget_max_linesr¥   )Útools.tool_output_limitsr¯   Úmaxr«   ÚDEFAULT_READ_OFFSETr‚   ÚDEFAULT_READ_LIMIT)r¬   r­   r¯   Únormalized_offsetÚnormalized_limits        r)   Únormalize_read_paginationr¶     sF   € õ
 7Ü˜Aœ{¨6Ô3FÓGÓHÐÜ˜1œc¤+¨eÔ5GÓ"HÉ-Ë/ÓZÓ[ÐØÐ.Ð.Ð.r7   c                 ój   — t        dt        | t        «      «      t        dt        |t        «      «      fS )zCReturn safe search pagination bounds for shell head/tail pipelines.r   r¥   )r±   r«   ÚDEFAULT_SEARCH_OFFSETÚDEFAULT_SEARCH_LIMIT)r¬   r­   s     r)   Únormalize_search_paginationrº   '  s.   € ô ˆq”+˜fÔ&;Ó<Ó=¼sÀ1ÄkÐRWÔYmÓFnÓ?oÐoÐor7   )*r.   ÚreÚdataclassesr   r   Útypingr   r   r   r   r	   r   r9   rC   rR   rX   rr   rz   ÚcompilerŽ   rŒ   ÚMr€   rƒ   r/   r1   r…   r”   r™   rž   r¡   r4   r2   r£   r    r²   r³   r¸   r¹   r«   r¶   rº   r6   r7   r)   ú<module>rÀ      sL  ðñó 
ß (ß 6Õ 6ð ÷oð oó ðoð* ÷cð có ðcð& ÷ð ó ððB ÷ð ó ðð ÷9ð 9ó ð9ðx ÷ð ó ðð  ÷ð ó ðð �2—:‘:ÐBÓCÐ Ø�2—:‘:ÐLÓMÐ ð �—‘Ð0°"·$±$Ó7€Ø�"—*‘*Ð1°2·4±4Ó8€ðW¨Sð W°Só Wð" cð "¨có "ð
 ð 
¨°©ó 
ð	 #ð 	¨sð 	°só 	ð €	ð�Sð ˜U 3¨ 9Ñ-ó ð5�8˜C‘=ð 5 Tó 5ð Ð ØÐ ØÐ ØÐ ð�sð  Sð ¨Só ð -@Ø+=ñ/ cð /Ø%(ð/ØBGÈÈSÈÁ/ó/ð /DØ-Añp¨ð pØ'*ðpØFKÈCÐQTÈHÁoôpr7   