
    sj[                       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mZm	Z	 ddl
mZ ddlmZmZmZmZ  eh d          Z edd	h          Z eh d
          Z eh d          Z eh d          Z eh d          Z ej        dej                  Z eh d          Z eh d          Z edh           eh d          dZ eh d          ZdZe G d d                      Z e G d d                      Z!d\dZ"d]d!Z#d^d%Z$d_d'Z%d`d,Z&dad0Z'dbd2Z(dcd6Z)ddd8Z*ded<Z+dfd=Z,dgd@Z-dhdAZ.didCZ/djdHZ0dkdJZ1dldLZ2dmdMZ3dndPZ4dodRZ5dpdSZ6dqdrdTZ7dsdUZ8	 dtdudXZ9dvdZZ:dwd[Z;dS )xzIDetect Git operations that can rewrite the checkout backing this process.    )annotationsN)	dataclassfield)Path)_bash_exec_payload%_deobfuscate_shell_word_for_detection_iter_shell_command_starts_read_shell_word>
   cherry-pickpullcleanmergebisectrebaserevertswitchrestorecheckoutmoveremove>   droplistshowclearstorecreate>   --hard--keep--merge>-   ls-treecat-filels-filesrev-listshow-ref	ls-remote	rev-parse
merge-base
range-diffformat-patchammvrmaddlogtagdiffgrephelpinitpushr   applyblamer   clonefetchnotesresetstashbranchbundlecommitconfigreflogremoterepackstatusreplacer   describeshortlogworktree	submodulemaintenance>   shkshzshbashdashz[A-Za-z_][A-Za-z0-9_]*=(.*)>   -T-g-h-p--host--user--group--chroot--prompt--close-from--command-timeout-C-R-c-u--chdir>   -S--argv0--unset--split-stringrZ   -ar]   r^   rc   >   -f-o--format--output)exectime>   rh   ri   nohupsetsidbuiltin   c                  P    e Zd ZU ded<   ded<   ded<    ee          Zded<   d	S )
_Heredocstr	delimiterbool
strip_tabsexecute_as_shell)default_factory	list[str]bodyN)__name__
__module____qualname____annotations__r   r   rw        9/home/agent/.hermes/hermes-agent/tools/self_repo_guard.pyro   ro      sQ         NNNeD111D111111r}   ro   c                  2    e Zd ZU ded<   ded<   dZded<   dS )_ShellContextrp   kindintopenerN
str | Nonequote)rx   ry   rz   r{   r   r|   r}   r~   r   r      s5         IIIKKKEr}   r   returnPath | Nonec                     	 t          t                                                    j        j        } n# t          t
          f$ r Y dS w xY w| dz                                  r| ndS )zAReturn the source checkout backing this process, if there is one.Nz.git)r   __file__resolveparentOSErrorRuntimeErrorexists)roots    r~   get_running_source_rootr      sl    H~~%%''.5\"   tt6M))++5445s   03 AApath_strrp   baser   c                    t          t          j                            |                     }|                                s||z  }	 |                                S # t          t          t          f$ r |cY S w xY wN)	r   ospath
expanduseris_absoluter   r   r   
ValueError)r   r   r   s      r~   _resolver      sz    ""8,,--D d{||~~\:.   s   A A76A7r   r   rr   c                v    	 | |k    p|                      |          S # t          t          t          f$ r Y dS w xY w)NF)is_relative_tor   r   r   )r   r   s     r~   
_is_withinr      sM    t|8t224888\:.   uus    88valuec                    t          |                     dd                    j                            d                                          S )N\/z.exe)r   rD   nameremovesuffixlower)r   s    r~   _executable_namer      s;    dC(()).;;FCCIIKKKr}   commandstartr   rv   c                    g }|}t          d          D ]R}t          | |          \  }}}||k    r n5|rd| ||         v r n%|                    t          |                     |}S|S )N@   
)ranger
   appendr   )r   r   wordscursor_
word_startword_endraw_words           r~   _shell_words_atr      s    EF2YY  )9'6)J)J&
Hh!!E 	TWVJ%6777E:8DDEEELr}   r   options_with_argfrozenset[str]c                   |}|t          |           k     rq| |         }|dk    r|dz   S |                    d          r|dk    rnB|                    dd          d         }d|vr
||v r|dz  }n|dz  }|t          |           k     q|S )N--   -=r      )len
startswithsplit)r   r   r   indexoptionoption_names         r~   _consume_optionsr      s    
 E
#e**

uT>>19  %% 	3ll3**1-f0@!@!@QJEEQJE #e**

 Lr}   ,tuple[dict[str, str], str | None, list[str]]c           	        i }d}|t          |           k     rIt                              | |                   r*| |                             dd          \  }}|||<   |dz  }^t	          | |                   }|dk    rt          | |dz   t                    }|dk    rt          | |dz   t                    }|dk    rJ|dz   t          |           k     r| |dz            dv r|d g fS t          | |dz   t                                }|t          v r;t          | |dz   t                              |t                                          }G|| |         | |dz   d          fS |d g fS )Nr   r   r   sudoenvr   >   -V-v)r   _ASSIGNMENT_RE	fullmatchr   r   r   _SUDO_OPTIONS_WITH_ARG_ENV_OPTIONS_WITH_ARG	frozenset_SIMPLE_WRAPPERS_WRAPPER_OPTIONS_WITH_ARGget)r   r   r   r   r   
executables         r~   _command_partsr      s   CE
#e**

##E%L11 	,,,S!44KD%CIQJE%eEl33
$UEAI7MNNE$UEAI7LMME""qy3u::%%%	*:l*J*JD"}$$UEAIy{{CCE)))$	)--j)++FF E
 E%L%	"444b=r}   starts	list[int]dict[int, tuple[int, ...]]c                   t          dd          g}i }d}t          t          |                    D ]A}||k     r|d         }|j        }| |         }|dk    r|dk    rd |_        |dz  }7|dk    r|dk    r|dz   |k     r|dz  }R|dk    rd |_        |dz  }e|                     d	|          r)|                    t          d	|                     |dz  }|d
k    r#|                    t          d
|                     |dz  }|dv r||_        |dz  }|dk    r|dz   |k     r|dz  }|                     d	|          r*|                    t          d	|                     |dz  }9|dk    r*|                    t          d|                     |dz  }i|dk    r=t          |          dk    r*|d         j        dv r|                                 |dz  }|d
k    r\t          |          dk    r&|d         j        d
k    r|                                 n#|                    t          d
|                     |dz  }||k     t          d |dd          D                       ||<   C|S )Nr   r   'r   "r   r   $(`   r   r   ()>   r   r   c              3  $   K   | ]}|j         V  d S r   )r   ).0items     r~   	<genexpr>z_scope_keys.<locals>.<genexpr>-  s$      CCddkCCCCCCr}   )
r   sortedsetr   r   r   r   r   poptuple)	r   r   contextsscopesr   r   contextr   chars	            r~   _scope_keysr      s   fb))*H)+FFF$$ 6D 6DunnrlGME6?D||3;;$(GM!||4<<FQJ$6$6aKF3;;$(GMaKF%%dF33 OOM$$?$?@@@aKF3;;OOM#v$>$>???!z!! $!t||
U 2 2!!!$// dF ; ;<<<!s{{c6 : :;;;!s{{s8}}q00Xb\5F+5U5U!s{{x==1$$"):c)A)ALLNNNNOOM#v$>$>???aKFg unnj CChqrrlCCCCCuMr}   r   c                N   |dz
  }d}|dk    rM| |                                          r3|p| |         dk    }|dz  }|dk    r| |                                          3|dk     r|rdnd S |dk    r"| |dz
  |dz            dv r| |dz
  |dz            S | |         dv r| |         S |rdnd S )Nr   Fr   r   >   ||&&>   {|&r   ;)isspace)r   r   r   saw_newlines       r~   _operator_beforer   2  s    AIEK
1**//11*!;WU^t%;
 1**//11* qyy",tt,qyyWUQY23|CCuqy519,--u~222u~(44D(r}   r   argscwdc                    t          |           dvrd S t          |dt                                }|t          |          k    s||         dk    rd S t	          ||         |          }|                                r|nd S )N>   cdpushdr   r   )r   r   r   r   r   is_dir)r   r   r   r   targets        r~   
_cd_targetr   A  s}    
##?::tT1ikk22ED		T%[C//td5k3''F]]__.66$.r}   c                &   t          |           \  }}|r|S t          |           D ]j\  }}|dk    r n^|                    d          r1d|dd         v r%|dz   t          |           k     r| |dz            ndc S |                    d          s nkdS )u  Return the script string owned by a shell's ``-c``, if present.

    Tries approval.py's ``_bash_exec_payload`` first: it parses bash's real
    option grammar (``-O/-o`` consume the next argument, short-option
    bundles, ``--init-file``/``--rcfile``), catching payloads a naive scan
    misses — ``bash -o pipefail -c '<script>'`` hides the ``-c`` behind an
    operand. When it finds no ``-c``, fall back to the permissive positional
    scan: ``_SHELL_EXECUTABLES`` also covers zsh/dash/ksh, whose option
    letters (``zsh -yc``, ``dash -Vc``) fall outside bash's alphabet and
    would otherwise make this block-guard fail open.
    r   r   cr   N)r   	enumerater   r   )r   has_cpayloadr   args        r~   _shell_script_argr  K  s     (--NE7 oo  
s$;;E>># 	F3#abb'>>&+ai#d))&;&;4	??EEE~~c"" 	E	4r}   linelist[_Heredoc]c                   g }d }d}|t          |           k     r| |         }|r6|dk    r"|dk    r|dz   t          |           k     r|dz  }F||k    rd }|dz  }T|dv r|}|dz  }`|                     d|          r|                     d|          r|dz  }|}|dz  }|t          |           k     o| |         d	k    }|r|dz  }|t          |           k     r,| |         d
v r"|dz  }|t          |           k     r
| |         d
v "|t          |           k    rn| |         dv r| |         nd }|r3|dz  }|                     ||          }|dk    rnp| ||         }	|dz   }n|}|t          |           k     r`| |                                         sF| |         dvr<|dz  }|t          |           k     r$| |                                         s
| |         dv<| ||         }	|}|	s| d |         }
t	          t          |
                    }|rt          |
|d                   ng }t          |          \  }}}t          |o@t          |          t          v o*t          |          d u ot          d |D                                  }|                    t          |	||                     |t          |           k     |S )Nr   r   r   r   r   r   z<<z<<<r   >    	r   z;|&<>c              3  F   K   | ]}|o|                     d            V  dS r   Nr   r   r  s     r~   r   z!_heredoc_specs.<locals>.<genexpr>  s6      HHC7CNN3$7$7 7HHHHHHr}   )r   r   findr   r   r	   r   r   rr   r   _SHELL_EXECUTABLESr  anyr   ro   )r  specsr   r   r   operator_atrs   delimiter_quoteendrq   headerr   r   r   r   r   rt   s                    r~   _heredoc_specsr  d  sX   EEE
#d))

E{ 	t||SYY1F1F
u}}QJE:EQJEtU++ 	tue/L/L 	QJE
SYY&=4;#+=
 	QJEc$iiDK;$>$>QJE c$iiDK;$>$>CII)-e
)B)B$u++ 	QJE))OU33CbyyU3YI!GEECc$iiS	(9(9(;(;S	QX@X@Xq c$iiS	(9(9(;(;S	QX@X@X U3YIE 	l{l#088997=Er
3332,U33:t I ,,0BBI!$''4/I HH4HHHHHH	
 
 	Xi5EFFGGGs #d))

v Lr}   c                @    d                     d | D                       S )N c              3  &   K   | ]}|d v r|ndV  dS )>   r   r  Nr|   )r   r   s     r~   r   z_masked_line.<locals>.<genexpr>  s0      JJT4<//44SJJJJJJr}   )join)r  s    r~   _masked_liner    s#    77JJTJJJJJJr}   tuple[str, list[str]]c                   g }g }g }|                      d          D ]}|r|d         }|                    d          }|j        r|                    d          }||j        k    rJ|j        r-|                    d                    |j                             |	                    d           n|j                            |           |                    t          |                     |                    |           |                    t          |                     	|D ]6}|j        r-|                    d                    |j                             7d                    |          |fS )NT)keependsr   z
r	  r  )
splitlinesrstriprs   lstriprq   rt   r   r  rw   r   r  extendr  )r   outputpendingshell_scriptsr  current	candidates          r~   _mask_heredocsr)    sr   F G!M""D"11 - - 	ajGF++I! 3%,,T22	G---+ @!(()>)>???A##D)))MM,t,,---d~d++,,,, 8 8# 	8  !6!6777776??M))r}   current_dirr   dict[str, str]2tuple[Path, str | None, list[str], dict[str, str]]c                &   |}d }i }d}|t          |           k     r| |         }|dk    r|dz  }n|dk    r5|dz   t          |           k     rt          | |dz            |          }|dz  }d|                    d          r1t          |          dk    rt          |dd          |          }|dz  }|dv r-|dk    r!|dz   t          |           k     r| |dz            }|dz  }|                    d          r#|                    d	d          d         }|dz  }|d
k    r|dz   t          |           k     ru| |dz            }|                                                    d          r<d	|v r8|                    d	d          \  }	}
|
||	dd                                          <   |dz  }|                    d          rKd	|v rG|dd                              d	d          \  }	}
|
||	dd                                          <   |dz  }|                    d          r|dz  } 	 |p|                    d          }|rt          ||          }|t          |           k     r| |                                         nd }||| |dz   d          |fS )Nr   r   r   rZ   r   >   	--git-dir--exec-path--namespace--work-treer1  z--work-tree=r   r\   alias.   z-calias.r   GIT_WORK_TREE)r   r   r   r   r   r   )r   r*  r   r   	work_treealiasesr   r  r?   keyr   explicit_work_tree
subcommands                r~   _git_target_and_subcommandr:    s   
 F I GE
#d))

5k$;;QJE$;;519s4yy00d519ov66FQJE>>$ 	CHHqLLc!""gv..FQJELLLm##	CII(=(= O	QJE>>.)) 			#q))!,IQJE$;;519s4yy00%!)_F||~~((22 1sf}}#\\#q11
U+0ABB(QJE>>*%% 	#**QRRsA..JC',GCGMMOO$QJE>># 	QJE">cggo&>&> 6,f55(-D		(9(9e""$$$tJ:tEAIKK0'99r}   r9  c                   | dk    r/t          j        d          t          fd|D                       S | dk    r#t          d |D             d          }|t          vS | dk    rt          d |D                       }| S | d	k    r7t          d
 |D                       }t          d |D                       }|p| S | t
          v S )Nr:   z--h(?:a(?:r(?:d)?)?)?\Zc              3  T   K   | ]"}|t           v p                    |          V  #d S r   )_RESET_WORKTREE_MODESr   )r   r  hards     r~   r   z$_mutates_worktree.<locals>.<genexpr>  s:      WW33//F4>>#3F3FWWWWWWr}   r;   c              3  D   K   | ]}|                     d           |V  dS r  r  r  s     r~   r   z$_mutates_worktree.<locals>.<genexpr>  s3      FFs#..2E2EFsFFFFFFr}   r4   r   c              3     K   | ]A}|d k    p6|                     d          o!|                     d           od|dd         v V  BdS )z	--dry-runr   r   nr   Nr  r  s     r~   r   z$_mutates_worktree.<locals>.<genexpr>  sz       
 
  ; Us##SCNN4,@,@(@SSCPQPRPRG^
 
 
 
 
 
r}   r   c              3  d   K   | ]+}|d k    p |                     d          od|dd         v V  ,dS )z--stagedr   Sr   Nr  r  s     r~   r   z$_mutates_worktree.<locals>.<genexpr>  s]       
 
 :I#.."5"5"H#QRR.
 
 
 
 
 
r}   c              3  d   K   | ]+}|d k    p |                     d          od|dd         v V  ,dS )z
--worktreer   Wr   Nr  r  s     r~   r   z$_mutates_worktree.<locals>.<genexpr>  s]       
 
 <KCNN3$7$7$JC3qrr7N
 
 
 
 
 
r}   )recompiler  next_STASH_SAFE_ACTIONS_WORKTREE_MUTATIONS)r9  r   actiondry_runstagedrG   r>  s         @r~   _mutates_worktreerN     s7   Wz455WWWWRVWWWWWWWFFdFFFOO000W 
 
 
 
 
 
 

 {Y 
 

 
 
 
 
  
 

 
 
 
 
 %v:%,,,r}   r   c                    |t          |           k     r6| |         }|dk    r|dz   S |                    d          r|dk    r|dz  }G|S |S )Nr   r   r   )r   r   )r   r   r  s      r~   _next_positionalrP    sa    
#d))

5k$;;19>># 	3#::QJELr}   c                (   t          | d          }|t          |           k    rdS | |                                         }|t          vrdS t          | |dz             }|t          |           k    rdS t	          | |         |          |k    rd| S dS )zKBlock `worktree remove|move` aimed at the running root, from any directory.r   Nr   zgit worktree )rP  r   r   _WORKTREE_TARGET_ACTIONSr   )r   r   r   action_indexrK  target_indexs         r~   _inspect_git_worktreerU  '  s    #D!,,Ls4yy  t,%%''F---t#D,*:;;Ls4yy  t\"C((D00'v'''4r}   r   aliasc           	         	 t          j        | dt          |          ddd| gdddd          }n# t          t           j        f$ r Y d S w xY w|j                                        }|j        d	k    r|r|nd S )
NrZ   r?   z--getr2  Tr   F)capture_outputtexttimeoutcheckr   )
subprocessrunrp   r   SubprocessErrorstdoutstrip
returncode)r   r   rV  resultr   s        r~   _read_git_aliasrc  7  s    	s6{{Hg?O?O?OP
 
 
 Z/0   ttM!!E%**u*55$>s   /2 AAdepthc           	     &   t          |||          \  }}}}	|d S |dk    rt          |||          S t          ||          sd S t          ||          rd| S |t          v rd S |t
          k    rd S |	                    |          }
|
t          | ||          }
|
sd S |
                    d          rt          |
dd          |||dz             S 	 t          j        |
d          }n# t          $ r Y d S w xY wt          | g |||i ||dz             S )NrG   zgit !r   T)posix)r:  rU  r   rN  _KNOWN_GIT_BUILTINS_MAX_RECURSIONr   rc  r   _find_mutationshlexr   r   _inspect_git)r   r   r*  r   r   rd  r   r9  sub_argsinline_aliasesrV  
alias_argss               r~   rl  rl  F  s    4Nk34 40FJ. tZ$Xvt<<<fd## tX.. #"j"""(((ttz**E}
FJ?? t BeABBiuqyAAA[d333

   tt * x 
	  s   C' '
C54C5c                    t          ||          sd S t          |           }t          |dt          h d                    }|||dz            ddgk    r| dS d S )Nr   >   --repo
--hostnamer[   r   prr   z pr checkout)r   r   r   r   )r   r   r*  r   r   r   s         r~   _inspect_github_clirt  t  sz     k4(( tJ''DT1i0N0N0N&O&OPPEEEAI4"444$$$$4r}   c           	     ^   |t           k    rd S t          |           \  }}|D ]}t          ||||dz             }|r|c S t          t	          t          |                              }t          ||          }	d|i}
i }|D ]*}|	|         }||
vr!|
                    |d d         |          |
|<   t          ||          }|	                    |d           }|	|dv r||
|<   t          ||          }t          |          \  }}}||
|         }t          |||          }||||<   t          |          }|dk    rt          ||||||          }|r|c S |dv rt          ||||          }|r|c S |t           v r,t#          |          }|rt          ||||dz             }|r|c S ,d S )Nr   r|   r   >   r   r   r   git>   ghhub)ri  r)  rj  r   r   r	   r   r   r   r   r   r   r   r   rl  rt  r  r  )r   r   r   rd  masked_commandheredoc_scriptsscript	operationr   r   cwd_by_scope
pending_cdr   scopeoperatorr%  r   r   r   r   r*  	cd_targetexecutable_names                          r~   rj  rj    sM   ~t&4W&=&=#NO!  "63eai@@	 		 C2>BBCCDDF00F13S	L.0J #% #%u$$"."2"25":s"C"CL#NE::..--8/@#@#@")L66 .u 5 5Z"5)z4==	  )Ju*:66e##$Z{CuUUI !    !--+Jk4PPI !    ! 222&t,,F %*6;eaiPP	 %$$$$4r}   c                 "    t           j        dk    S )u  Whether the self-repo git guard applies on this platform.

    Windows-only: NTFS locks loaded .py/.pyd files and an in-place overwrite
    of the live checkout can corrupt the running process. On POSIX, open file
    handles keep the old inode alive, so a checkout swap under a running
    process is safe — already-imported modules keep executing the old code
    and the mixed-module hazard is limited to later lazy imports, which is
    not worth blocking every git workflow for.
    nt)r   r   r|   r}   r~   guard_activer    s     7d?r}   source_roottuple[bool, str | None]c                0   ||nt                      }|| sdS t          t          |          t          d                    }|rt          |t          d                    nt          d          }t	          | ||          }|dS dt          ||          fS )z@Return whether a command would rewrite the live source checkout.N)FNr   T)r   r   rp   r   rj  _block_message)r   r   r  r   r   r|  s         r~   detect_self_repo_git_mutationr    s     &1;;7N7P7PD|7|{CIItCyy))D'*98Cc###S		Dwd33I{	40000r}   r|  c           	     <    t                      }d|  d| d| d| d	S )Nz
Blocked: `z/` would rewrite Hermes's live source checkout (z) and can mix module versions in this running process. Use a separate worktree or a shared clone on real disk, e.g. `git clone --shared r  u&  /<task>` — avoid /tmp for clones that install node/python deps: /tmp is usually RAM-backed tmpfs and a few dependency installs can fill it and ENOSPC other work. Delete the clone when the branch is pushed. To change this checkout, stop Hermes, run the command externally, then restart Hermes.)_scratch_dir_hint)r|  r   scratchs      r~   r  r    sS    !!G	Y 	 		 	  $	 	 '.	 	 	
r}   c                     t           j                            dd                                          } | r!t	          |                                           nt	          j                    dz  }t          |dz            S )zFDisk-backed scratch location suggested to agents for temporary clones.HERMES_HOMEr  z.hermesr  )r   environr   r`  r   r   homerp   )hermes_homer   s     r~   r  r    sd    *..3399;;K-8U4'')))dikkI>UDti   r}   )r   r   )r   rp   r   r   r   r   )r   r   r   r   r   rr   )r   rp   r   rp   )r   rp   r   r   r   rv   )r   rv   r   r   r   r   r   r   )r   rv   r   r   )r   rp   r   r   r   r   )r   rp   r   r   r   r   )r   rp   r   rv   r   r   r   r   )r   rv   r   r   )r  rp   r   r  )r  rp   r   rp   )r   rp   r   r  )r   rv   r*  r   r   r+  r   r,  )r9  rp   r   rv   r   rr   )r   rv   r   r   r   r   )r   rv   r   r   r   r   r   r   )r   rp   r   r   rV  rp   r   r   )r   rp   r   rv   r*  r   r   r+  r   r   rd  r   r   r   )
r   rp   r   rv   r*  r   r   r   r   r   )r   )
r   rp   r   r   r   r   rd  r   r   r   )r   rr   r   )r   rp   r   r   r  r   r   r  )r|  rp   r   r   r   rp   )r   rp   )<__doc__
__future__r   r   rF  rk  r\  dataclassesr   r   pathlibr   tools.approvalr   r   r	   r
   r   rJ  rR  rI  r=  rh  r  rG  DOTALLr   r   r   r   r   ri  ro   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r)  r:  rN  rP  rU  rc  rl  rt  rj  r  r  r  r  r|   r}   r~   <module>r     s   O O " " " " " " 				 				      ( ( ( ( ( ( ( (                   i ! ! !    %9fh%788 i T T TUU !	"A"A"ABB i 4! 4! 4! 4 4 j YCCCDD :BIFF" $ $ $   $ "	 	# 	# 	# 	 	  ItfI:::;;   9KKKLL  2 2 2 2 2 2 2 2        6 6 6 6      L L L L      (       F= = = =@) ) ) )/ / / /   2@ @ @ @FK K K K* * * *:5: 5: 5: 5:p- - - -6	 	 	 	    ? ? ? ?+ + + +\   4 4 4 4 4n
 
 
 
   $1 1 1 1 1$   ! ! ! ! ! !r}   