Ë
    ãß²jÂ:  ã                   ó’  — 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mZ ddlm	Z	 ddl
mZmZ  ej                  d«      Zedefd„«       Zd	d
ddddddddddœZeeef   ed<   dededz  fd„Zi ej-                  dddi«      ¥ej-                  dddi«      ¥ej-                  dddi«      ¥dd id!d"d#d$d%œdd&id'œ¥Zeeeeef   f   ed(<   d)Zd*edededz  fd+„Zd*ed,ed-edeeeef   fd.„Zdefd/„Zd,edefd0„Zd*ed1ed,edee   fd2„Zde eeef      fd3„Z!dee   fd4„Z"d*ed5ed6ed-ed7ed8ee   d9ee   d:ed;ee   d<ee   d=ee   defd>„Z#y)?a7  Foreground result post-processing for the terminal tool (cwd dual-write,
sudo handling, transform hook, truncation, ANSI strip, redaction, exit-code
notes/hints, spill redaction, verification evidence) + exit-code tables. Lazy
``tools.terminal_tool`` lookups keep the origin's monkeypatch points authoritative.
é    N)Úcontextmanager)ÚPath)ÚAnyÚOptionalztools.terminal_toolÚlabelc              #   ód   K  — 	 d–— y# t         $ r t        j                  d| d¬«       Y yw xY w­w)z>Best-effort block: swallow any exception, logging it at DEBUG.Nz	%s failedT©Úexc_info)Ú	ExceptionÚloggerÚdebug)r   s    ú?/home/ubuntu/.hermes/hermes-agent/tools/terminal_tool_result.pyÚ_quietr      s.   è ø€ ð8ÜøÜò 8Ü�‰�[ %°$ˆÖ7ð8üs   ‚0„	 ˆ0‰!-ª0¬-­0zSIGQUIT (quit from keyboard)uE   SIGILL (illegal instruction â€” corrupt binary or wrong architecture)uJ   SIGABRT (abort â€” assertion failure, fatal runtime error, or glibc abort)u;   SIGBUS (bus error â€” misaligned or unmapped memory access)z>SIGFPE (fatal arithmetic error, e.g. integer division by zero)uT   SIGKILL â€” often the kernel OOM killer on memory exhaustion, or an explicit kill -9u4   SIGSEGV (segmentation fault â€” the program crashed)uN   SIGPIPE (wrote to a closed pipe â€” e.g. output piped to a reader that exited)uF   SIGTERM (terminated â€” kill/timeout or shutdown requested it to stop)z!SIGXCPU (CPU time limit exceeded)z"SIGXFSZ (file size limit exceeded))é   é   é   é   é   é	   é   é   é   é   é   Ú_SIGNAL_EXIT_NOTESÚ	exit_codeÚreturnc                 ó2  — | dk  rQ|  }|dk(  ryt         j                  |«      x}rd|› d|› �S 	 t        j                  |«      j                  }d|› d|› d	�S | d
kD  r(t         j                  | d
z
  «      x}rd| › d| d
z
  › d|› �S y# t
        $ r d|› �}Y ŒGw xY w)zÚNote for a signal-termination exit code, or None. Negative codes are
    definite (subprocess semantics); 128+signum is the shell convention and a
    program *can* exit 139 itself, so those notes hedge with "usually".r   é   NzCommand terminated by signal z: zsignal zCommand terminated by z	 (signal ú)é€   z
Exit code z4 usually means the command was terminated by signal )r   ÚgetÚsignalÚSignalsÚnameÚ
ValueError)r   ÚsignumÚnoter%   s       r   Ú_interpret_signal_exitr)   /   sÞ   € ð �1‚}Ø�ˆØ�QŠ;ØÜ%×)Ñ)¨&Ó1Ð1ˆ4Ð1Ø2°6°(¸"¸T¸FÐCÐCð	&Ü—>‘> &Ó)×.Ñ.ˆDð (¨ v¨Y°v°h¸aÐ@Ð@Ø�3‚Ô$6×$:Ñ$:¸9Às¹?Ó$KÐK˜DÐKØ˜Y˜Kð ((Ø(1°C©Ð'8¸¸4¸&ðBð 	Càøô ò 	&Ø˜V˜HÐ%ŠDð	&ús   ¯B ÂBÂB)ÚgrepÚegrepÚfgrepÚrgÚagÚacké   zNo matches found (not an error))ÚdiffÚ	colordiffz%Files differ (expected, not an error))Útestú[z5Condition evaluated to false (expected, not an error)zGSome directories were inaccessible (partial results may still be valid)zCould not resolve hostzFailed to connect to hostz2HTTP response code indicated error (e.g. 404, 500)zOperation timed out)r   r   é   é   uL   Non-zero exit (often normal â€” e.g. 'git diff' returns 1 when files differ))ÚfindÚcurlÚgitÚ_EXIT_CODE_SEMANTICSu;  The execution environment was recreated while running this command (the previous container/sandbox was gone). Persistent files were restored where the backend supports it, but background processes and any files outside persisted paths from earlier commands may be lost â€” verify state before relying on prior work.Úcommandc                 ó  — |dk(  ryt        |«      x}�|S t        j                  d| «      }|r|d   n| j                  «       }t	        d„ |j                  «       D «       d«      }t
        j                  |i «      j                  |«      S )zÜNote for a non-zero exit code that is informational rather than an
    error (grep=1 "no matches", diff=1 "files differ", signal deaths), so the
    model doesn't burn turns investigating it. None when 0 or a real error.r   Nz\s*(?:\|\||&&|[|;])\s*éÿÿÿÿc              3   ón   K  — | ]-  }d |vs|j                  d«      r|j                  d«      d   –— Œ/ y­w)Ú=Ú-ú/r=   N)Ú
startswithÚsplit)Ú.0Úws     r   ú	<genexpr>z'_interpret_exit_code.<locals>.<genexpr>o   s6   è ø€ ò ;¨!Ø 1™¨¯©°SÔ(9ð —W‘W˜S“\ "Õ%ñ ;ùs   ‚35Ú )r)   ÚrerC   ÚstripÚnextr:   r"   )r;   r   Úsignal_noteÚsegmentsÚlast_segmentÚbase_cmds         r   Ú_interpret_exit_coderO   \   s�   € ð �A‚~ØÜ-¨iÓ8Ð8ˆÐEð Ðô �x‰xÐ1°7Ó;€HÙ$,�H˜R’L°'×@Ñ@ÓB€LÜñ ;¨|×/AÑ/AÓ/Cô ;Ø<>ó@€Hä×#Ñ# H¨bÓ1×5Ñ5°iÓ@Ð@ó    ÚoutputÚenv_typec                 óÒ   — ddl m} ddlm}m}m}m} ddlm}  |||«      } ||«      }	 || |«      }
|
xr& |j                  «       duxs  |d«      xr  |«        }|r|dz  }||	|
fS )z>Sudo failure handling -> (output, auth_failed, cache_cleared).r   N)Ú_handle_sudo_failureÚ_in_delegated_child_contextÚ'_invalidate_cached_sudo_on_auth_failureÚ_sudo_wrong_password_failure)Úenv_var_enabledÚHERMES_INTERACTIVEuu   

âš ï¸� Sudo authentication failed â€” cached password cleared. You will be prompted again on the next sudo command.)
Útools.terminal_toolÚterminal_toolÚtools.terminal_tool_sudorT   rU   rV   rW   ÚutilsrX   Ú_get_sudo_password_callback)r;   rQ   rR   ÚttrT   rU   rV   rW   rX   Úauth_failedÚcache_clearedÚcan_reprompts               r   Ú_sudo_annotationsrc   t   s�   € å$÷ó õ &Ù! &¨(Ó3€FÙ.¨vÓ6€KÙ;¸GÀVÓL€MØ ò ,Ø
×&Ñ&Ó(°Ð4Ò]¹ÐH\Ó8]ò,á)Ó+Ð
+ð ñ Øð Sñ 	Tˆà�; Ð-Ð-rP   c                 óÈ   — t        d«      5  ddlm} ddlm}  |d| |||xs d||j                  «       ¬«      }t        d„ |D «       |«      }d	d	d	«       |S # 1 sw Y   |S xY w)
zŽPlugin output-transform seam (fail-open; first string result wins).
    Replacements are still subject to the output limit applied afterwards.ztransform_terminal_output hookr   )Úinvoke_hook)Ú_approval_tool_call_idÚtransform_terminal_outputrG   )r;   rQ   Ú
returncodeÚtask_idrR   Útool_call_idc              3   óB   K  — | ]  }t        |t        «      sŒ|–— Œ y ­w)N)Ú
isinstanceÚstr)rD   Úrs     r   rF   z/_apply_output_transform_hook.<locals>.<genexpr>“   s   è ø€ Ò@˜Q¬Z¸¼3Õ-?”qÑ@ùs   ‚˜N)r   Úhermes_cli.lifecyclere   Útools.approval_contextrf   r"   rJ   )r;   rQ   rh   ri   rR   re   rf   Úresultss           r   Ú_apply_output_transform_hookrr   ˆ   su   € ô 
Ð0Ó	1ñ JÝ4ÝAñ Ð9À7ÐSYØ)3¸Wº]ÈÐU]Ø+A×+EÑ+EÓ+GôIˆô Ñ@ 'Ô@À&ÓIˆ÷Jð €M÷Jð €Mús   ŒAAÁA!c                 ó6   — ddl m} ddlm}  ||  |«       «      S )Nr   )Úget_max_bytes)Útruncate_head_tail)Útools.tool_output_limitsrt   Útools.tool_output_truncateru   )rQ   rt   ru   s      r   Ú_truncate_head_tailrx   —   s   € Ý6Ý=Ù˜f¡m£oÓ6Ð6rP   rh   c                 óÎ   — t        d«      5  ddlm} |dk(  r|j                  | |«      cddd«       S |s|j	                  | ||«      cddd«       S 	 ddd«       y# 1 sw Y   yxY w)zÝRecovery hints for well-known failure shapes (tools/terminal_hints.py);
    on rc=0, warn when a pipeline tail / `|| echo` may mask an upstream
    failure and the output carries strong failure indicators (advisory only).zfailure hintr   )Úterminal_hintsN)r   Útoolsrz   Úannotate_masked_successÚannotate_failure)r;   rh   rQ   Ú	exit_noterz   s        r   Ú_failure_hintr   �   sw   € ô 
�Ó	ñ PÝ(Ø˜Š?Ø!×9Ñ9¸'À6ÓJ÷Pñ Pñ Ø!×2Ñ2°7¸JÈÓO÷Pñ Pð ÷	Pð ÷Pð ús   ŒA³AÁA$c                 óœ  — | sg S 	 ddl m} ddlm} ddlm} t        | «      j                  dd¬«      } |t        | «       | ||«      |«      ddd¬	«       d|d›d| › d�}d|fd| fd|fgS # t        $ rV t        j                  d
d¬«       t        d«      5  t        | «      j                  «        ddd«       n# 1 sw Y   nxY wg cY S w xY w)zÜSpill handle so the model can read the omitted middle instead of
    re-running. The collector wrote it raw; redact it with the same pass so no
    secret persists unmasked on disk. On failure drop the handle (and file).r   ©Úredact_terminal_output©Ú
strip_ansi)Úwrite_text_exclusivezutf-8Úreplace)ÚencodingÚerrorsT)ÚprivateÚ	overwriterˆ   z-spill redaction failed; dropping spill handler	   zspill unlinkNzCOutput exceeded the capture window (head+tail shown). Full output (ú,z chars) saved to u]    â€” search it with search_files or page it with read_file instead of re-running the command.Úoutput_total_charsÚfull_output_pathÚtruncation_note)Úagent.redactr‚   Útools.ansi_stripr„   Útools.spill_safetyr…   r   Ú	read_textr   r   r   r   Úunlink)ÚpathÚtotal_charsr;   r‚   r„   r…   Ú	raw_spillr(   s           r   Ú_redact_spill_filer—   ª   sò   € ñ Øˆ	ðÝ7Ý/Ý;Ü˜“J×(Ñ(°'À)Ð(ÓLˆ	ñ 	œT $›ZÑ)?Á
È9Ó@UÐW^Ó)_Ø%)°TÀ)õ	MðØ'¨˜?Ð*;¸D¸6ð BXðX€Dð " ;Ð/Ð2DÀdÐ1KÐN_ÐaeÐMfÐgÐgøô ò Ü�‰ÐDÈtˆÔTÜ�NÓ#ñ 	 Ü�‹J×ÑÔ÷	 ÷ 	 ñ 	 úàŠ	ð	ús*   †AA, Á,+CÂB:Â1	CÂ:C	Â?	CÃ
Cc                 óÌ   — t        d«      5  ddlm}  || ||||¬«      }|r)dD �ci c]  }||j                  |«      “Œ c}cd d d «       S 	 d d d «       y c c}w # 1 sw Y   y xY w)Nzverification evidence recordingr   )Úrecord_terminal_result)r;   ÚcwdÚ
session_idr   rQ   )ÚstatusÚkindÚscopeÚcanonical_command)r   Úagent.verification_evidencer™   r"   )r;   rš   r›   rh   rQ   r™   ÚevidenceÚks           r   Ú_verification_evidencer£   Ä   sv   € Ü	Ð1Ó	2ñ bÝFÙ)°'¸sÈzØ4>ÀvôOˆáØ0`Öa¨1�A�x—|‘| A“Ñ&Òa÷bñ bð ÷	bð ùò b÷bð ús   ŒA¦A¿AÁAÁA#ÚresultÚenvÚeffective_task_idri   r›   Úsession_keyÚworkdirÚcommand_cwdÚapproval_notec           	      óŒ  — ddl m} d}|xs i j                  d«      r$|xs i j                  d«      xs t        |dd«      }|s|r	 |||«       |j                  dd«      }|j                  dd«      }t	        | ||«      \  }}}t        | ||||«      }t        |«      }dd	lm} dd
l	m
}  ||«      }|r ||j                  «       | «      nd}t        | |«      }t        | |||«      }d}t        d«      5  |r^|	r\t        j                   j#                  t%        |«      «      t        j                   j#                  t%        |	«      «      k7  rt%        |«      }ddd«       |
r|dk(  rd|v r|
j'                  d«      dz   }
||ddœ}d|fd|j                  d«      rt(        ndfgt+        |j                  d«      |j                  d«      | «      ¢dt-        | |	|xs
 |xs |xs d||«      f‘d|
xs df‘d|xs df‘d|xs df‘d|rdndf‘d|rdndf‘}|D ]  \  }}|€Œ	|||<   Œ t/        j0                  |d¬«      S # 1 sw Y   ŒæxY w)zETurn a raw ``env.execute`` result into the tool's JSON result string.r   )Úrecord_session_cwdNÚcwd_observedrš   rQ   rG   rh   r�   rƒ   zcwd comparisoné‚   z[Command interrupted]ú.z, then interrupted.)rQ   r   ÚerrorÚenvironment_recreatedr�   rŒ   Úverification_evidenceÚdefaultÚapprovalÚexit_code_meaningÚhintÚsudo_auth_failedTÚsudo_cache_clearedF)Úensure_ascii)rZ   r¬   r"   Úgetattrrc   rr   rx   r�   r‚   r�   r„   rI   rO   r   r   Úosr”   Úrealpathrm   ÚrstripÚ_ENV_RECREATED_NOTEr—   r£   ÚjsonÚdumps)r;   r¤   r¥   rR   r¦   ri   r›   r§   r¨   r©   rª   r¬   Úobserved_cwdrQ   rh   r·   r¸   r‚   r„   r~   Úfailure_hintÚchanged_cwdÚresult_dictÚoptional_fieldsÚkeyÚvalues                             r   Úfinalize_foreground_resultrÈ   Î   s¯  € õ 7ð €LØŠ�"×Ñ˜.Ô)Øš "×)Ñ)¨%Ó0ÒM´G¸CÀÈÓ4MˆÙ‘|Ù˜;¨Ô5à�Z‰Z˜ "Ó%€FØ—‘˜L¨!Ó,€JÜ3DÀWÈfÐV^Ó3_Ñ0€FÐÐ0Ü)¨'°6¸:ÐGXÐZbÓc€FÜ  Ó(€Fõ 4Ý+Ù˜Ó€Fñ AGÑ# F§L¡L£N°GÔ<ÈB€Fä$ W¨jÓ9€IÜ  ¨*°f¸iÓH€Lð €KÜ	Ð Ó	!ñ ,Ù™K¬B¯G©G×,<Ñ,<¼SÀÓ=NÓ,OÔSU×SZÑSZ×ScÑScÔdgÐhsÓdtÓSuÒ,uÜ˜lÓ+ˆK÷,ñ ˜ sÒ*Ð/FÈ&Ñ/PØ%×,Ñ,¨SÓ1Ð4IÑIˆà#°*ÀtÑL€Kð 
�ÐØ	 ¸¿¹ÐD[Ô9\Õ"5ÐbfÐgð.ô 
˜FŸJ™JÐ'9Ó:¸F¿J¹JÐG[Ó<\Ð^eÓ	fð.ð 
!Ô"8Ø�[ *Ò"Y°Ò"YÐ;LÒ"YÐPYØ˜ó# ð 	!ð	.ð 
�]Ò* dÐ+ð.ð 
˜iÒ/¨4Ð0ð.ð 
�Ò% Ð&ð.ð 
Ñ%5™T¸4Ð@ð.ð 
Ñ'9™t¸tÐDð.€Oð &ò %‰
ˆˆUØÑØ$ˆK˜Òð%ô �:‰:�k°Ô6Ð6÷9,ð ,ús   Ã4A!H:È:I)$Ú__doc__r¿   Úloggingr»   rH   r#   Ú
contextlibr   Úpathlibr   Útypingr   r   Ú	getLoggerr   rm   r   r   ÚdictÚintÚ__annotations__r)   Úfromkeysr:   r¾   rO   ÚtupleÚboolrc   rr   rx   r   Úlistr—   r£   rÈ   © rP   r   ú<module>r×      sš  ðòó Û Û 	Û 	Û Ý %Ý ß  à	ˆ×	Ñ	Ð0Ó	1€ð ð8�#ò 8ó ð8ð 	'ØOØTØEØHØ^Ø>ØXØPØ+Ø,ñ&Ð �D˜˜c˜‘Nó ð cð ¨c°D©jó ð,3Ø
‡m�mÐAÀAÐGhÐCiÓjð3à
‡m�mÐ)¨AÐ/VÐ+WÓXð3ð ‡m�m�M AÐ'^Ð#_Ó`ð3ð ÐYÐZØ(Ð-HØEÐK`ñbàÐ]Ð^ò3Ð �d˜3  S¨# X¡Ð.Ñ/ó ð$ð ðA #ð A°#ð A¸#À¹*ó Að0.˜sð .¨Cð .¸3ð .À5ÈÈdÐTXÈÑCYó .ð(ÐTWó ð7 ð 7¨ó 7ð
˜3ð 
¨Cð 
¸ð 
ÈHÐUXÉMó 
ðh°d¸5ÀÀcÀ¹?Ñ6Kó hð4ÈHÐUYÉNó ðG7ØðG7Ø!ðG7Ø(+ðG7Ø7:ðG7ØORðG7à�c‰]ðG7à(0°©ðG7àDGðG7ð �c‰]ðG7ð *2°#©ðG7ð HPÐPSÁ}ðG7ð 	ô	G7rP   