+
    „WÝjZ   ã                   ó"  € R t ^ RIt^ RIt^ RIt^ RIHtHt ^ RIt^ RIt^ RI	H	t	H
t
HtHt ^ RIHt ^ RIHt ^ RIHtHtHt ^ RIHt ]P.                  ! R4      t^
t^t]! R	R	R
R]! 4       R7      tRktRtR R ltRlRRRR/R llt R R lt!]]3R R llt"R R lt#RmR R llt$RmR R llt%R R lt&R R!R"R#/t'R$ R% lt(R& R' lt)0 Rnmt*R(t+R)t,R* R+ lt-R, R- lt.R. R/ lt/R0 R1 lt0R2 R3 lt1R4 R5 lt2R6 t3R7 R8 lt4R9 R: lt5 ! R; R<]64      t7R=RR>RR?R/R@ RA llt8RB RC lt9RD RE lt:RF RG lt;RH RI lt<RJ RK3RL RM3RN RO3RP RQ3RR RS3RT RU33t=RV RW lt>RXRRYR/RZ R[ llt?R\ R] lt@R^ R_ ltAR` Ra ltBRb Rc ltCRd Re ltDRf Rg ltERh tFR?R/Ri ltGR?R/Rj ltHR# )oa¤  Git plumbing for ``hermes update``: fork/upstream sync, trampoline-git detection, lockfile/EOL churn cleanup, orphan rescue refs, parked-branch assessment, fetch-failure classification.

Split out of ``update_cmd.py``, which re-imports every name so ``hermes_cli.update_cmd.<name>``
still resolves/monkeypatches. Origin helpers are imported lazily per function (no cycle;
test patches on ``update_cmd`` stay effective).
N)ÚnullcontextÚsuppress)ÚdatetimeÚ	timedeltaÚtimezoneÚUTC)ÚPath)ÚOptional)ÚNO_LAZY_FETCH_ENVÚnoninteractive_git_envÚwindows_hide_flags)Ú_record_stopzhermes_cli.update_cmdTúutf-8Úreplace)Úcapture_outputÚtextÚencodingÚerrorsÚcreationflagszHgit remote add upstream https://github.com/NousResearch/hermes-agent.gitc                ó$   € V ^8„  d   QhR\         /# ©é   Úreturn©Úbool)Úformats   "ÚMC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\update_cmd_git.pyÚ__annotate__r   #   s   € ÷ =ñ =¬ñ =ó    c                ó    € \        WV3/ VB RJ# )z@True when ``_git_run`` exits 0; any exception counts as failure.N©Ú_git_stdout)Úgit_cmdÚargsÚcwdÚkws   &&&,r   Ú_git_okr&   #   s   € ä�w cÑ0¨RÑ0¸Ð<Ð<r   ÚcheckFÚenvc               óT   € ^ RI Hp V! V \        V4      VRRRRV\        4       VR7
      # )a4  Run ``git_cmd + args`` and return the CompletedProcess.

The updater's git runner: capture all output and decode as UTF-8 regardless of the
Windows ANSI code page (#52649). ``check=True`` raises on non-zero exit. The spawn
always hides its console window (#117781). ``env`` replaces the child's environment.
©Úrun_gitTr   r   )r$   r   r   r   r   r'   r   r(   )Úhermes_cli.update_custodyr+   Úlistr   )r"   r#   r$   r'   r(   r+   s   &&&$$ r   Ú_git_runr.   (   s8   € õ 2ñ Ø”�d“ØØØ˜G¨IØÜ(Ó*Øôð r   c                ó:   € V ^8„  d   QhR\         \        ,          /# r   )r	   Ústr)r   s   "r   r   r   =   s   € ÷ ñ ¬X´c­]ñ r   c                óú   € ^ RI Hp \        \        4      ;_uu_ 4        V! WV3/ VB pVP                  ^ 8X  d%   VP
                  P                  4       uuRRR4       #  RRR4       R#   + '       g   i     R# ; i)zYStripped stdout of a successful ``_git_run``; ``None`` on non-zero exit or any exception.©r.   N)Úhermes_cli.update_cmdr.   r   Ú	ExceptionÚ
returncodeÚstdoutÚstrip)r"   r#   r$   r%   r.   Úresults   &&&,  r   r!   r!   =   sb   € å.Ü	”)×	Õ	Ù˜'¨Ñ3°Ñ3ˆØ×Ñ Ô!Ø—=‘=×&Ñ&Ó(÷ 
Ò	à!÷ 
ñ ÷	 
Ö	ñ ús   ž5A)Á)A:	c                ó   € V ^8„  d   QhRR/# ©r   r   N© )r   s   "r   r   r   G   s   € ÷ &>ñ &>à	ñ&>r   c                ó®  € ^ RI Hp \        \        4      ;_uu_ 4        \	        4       pR EFQ  pRV RV R2pV! V RRRV R2.V4      p	V	P
                  ^ 8w  d   K1  V	P                  P                  4        U
u. uF*  qªP                  4       '       g   K  V
P                  4       NK,  	  pp
T\	        V^ 8”  d   VRV)  MT4      ,          pV^ 8”  g   K§  \        P                  ! \        4      \        VR	7      ,
          pV Fy  p\        \        4      ;_uu_ 4        \        P                  ! V\        V4      R R
,          R4      pVP!                  \        R7      V8  d   VP#                  V4       RRR4       K{  	  EKT  	  \%        V4       F  pV! V RRV.V4       K  	  RRR4       R# u up
i   + '       g   i     KÁ  ; i  + '       g   i     R# ; i)uù  Expire old rescue refs (``refs/hermes-update-backups/<kind>-<branch>-<ts>-<sha>``).

``<kind>`` is ``orphan`` (no common ancestor), ``diverged`` (local commits on the target
branch) or ``detached`` (commits made on a detached HEAD the update moved off). All are written
before the update moves HEAD and all pin objects, so they expire on the same terms; each kind
keeps its own ``keep`` newest.

Each ref pins a possibly multi-GB snapshot against ``git gc``, so a repeatedly corrupted install would
grow ``.git`` unbounded. Keep the ``keep`` newest AND drop any older than ``max_age_days`` by the
``YYYYMMDD-HHMMSS`` stamp (unparseable names left alone); names sort chronologically so
``for-each-ref`` order is creation order. Best-effort, never blocks.

A rescue ref pins every object reachable from that commit against ``git gc`` â€” and in the incident shape
those objects include a full working-tree snapshot (the autostash orphan commit), which can be multi-GB
when the tree holds large stray files. See #87694.
r2   zrefs/hermes-update-backups/Ú-úfor-each-refú--format=%(refname)z--sort=refnameÚ*N)ÚdaysºNé   Nú%Y%m%d-%H%M%S)Útzinfoú
update-refz-d)ÚorphanÚdivergedÚdetached)Úhermes_cli.update_cmd_gitr.   r   ÚOSErrorÚsetr5   r6   Ú
splitlinesr7   r   Únowr   r   Ú
ValueErrorÚstrptimeÚlenr   ÚaddÚsorted)r"   r$   ÚbranchÚkeepÚmax_age_daysr.   ÚstaleÚkindÚprefixÚlist_resultÚlineÚrefsÚcutoffÚrefÚstamps   &&&&&          r   Ú_prune_orphan_rescue_refsr`   G   s‹  € õ& 3Ü	”'×	Õ	Ü›%ˆÜ6ˆDØ2°4°&¸¸&¸ÀÐCˆFÙ"Ø˜.Ð*?ÐAQÐV\ÐU]Ð]^ÐS_Ð`ÐbeógˆKà×%Ñ%¨Ô*ÙØ-8×-?Ñ-?×-JÑ-JÔ-LÓ]Ñ-L T×PZÑPZ×P\”L�D—J‘J–LÑ-LˆDÐ]Ø”S¨°¬˜˜f ˜u™°tÓ<Õ<ˆEØ˜aÖÜ!Ÿš¤cÓ*¬Y¸LÔ-IÕI�Û�CÜ!¤*×-Õ-Ü (× 1Ò 1°#´c¸&³k°lÐ2CÀCÕ2HÈ/Ó Z˜Ø Ÿ=™=´˜=Ó4°vÔ=Ø!ŸI™I cœN÷ .Ñ-ô  ñ 7ô ˜%–=ˆCÙ�W˜|¨T°3Ð7¸Ö=ñ !÷# 
Ñ	ùò ^÷
 .×-Ð-ú÷ 
×	Ð	úsD   žAGÁ8F*
ÂF*
Â(%GÃAGÄAF/Å00GÆ*GÆ/G Æ:	GÇG	c                ó   € V ^8„  d   QhRR/# r:   r;   )r   s   "r   r   r   p   s   € ÷ #4ñ #4°ñ #4r   c           
     óæ  € ^ RI Hp V! V . R OV4      P                  ^ 8X  d   R# V! V . R!OV4      pVP                  ;'       g    RP	                  4       pVP                  ^ 8w  g	   V'       g   R# V! V RRVR.V4      pVP                  ;'       g    RP                  4        Uu. uF  qwR8w  g   K  VNK  	  ppVP                  ^ 8X  d   V'       d   R# \        P                  ! \        4      P                  R4      p	R	V R
V	 R
VR,           2p
V! V RW¥.V4      P                  ^ 8w  dS   \        RVR,           RV
 R24       \        RV RVR,           24       \        R4       \        P                  ! ^4       V! V RRVRRRR.V4      P                  ;'       g    RP	                  4       p\        RT;'       g    R RV
 R\         R24       \        RV
 R24       \        WV4       R# u upi )"an  Keep commits made on a detached HEAD reachable before the update moves HEAD off it.

Such commits belong to no branch: once HEAD moves, only the expiring reflog still reaches them,
and nothing in the output would name them. When HEAD is detached at a commit no ref contains
(the autostash's ``refs/stash`` does not count: it is dropped after the update), write
``refs/hermes-update-backups/detached-<branch>-<ts>-<sha12>`` (the divergence rescue refs'
scheme and expiry) and name it. When that write fails, refuse (``sys.exit(1)``) rather than
orphan the work. Attached HEADs and already-reachable commits are left alone.
r2   NÚ r>   z
--containsr?   z
refs/stashrD   z$refs/hermes-update-backups/detached-r=   :Né   NrF   u   âœ— HEAD is detached at z8, which no branch or tag contains, and backing it up to z failed.zK  Update stopped so those commits are not orphaned. Keep them with: git -C z branch <name> Údetached_headúrev-listú--countz--notz
--branchesz--tagsz	--remotesu     âš  ÚSomeuG    commit(s) made on the detached HEAD are on no branch â€” backed up to z/ before moving HEAD. This backup expires after z days.z    List them with: git log z" --not --branches --tags --remotes)zsymbolic-refú-qÚHEAD)ú	rev-parseú--verifyú--quietzHEAD^{commit})r3   r.   r5   r6   r7   Úsplitr   rN   r   ÚstrftimeÚprintr   ÚsysÚexitÚ_ORPHAN_RESCUE_REF_MAX_AGE_DAYSr`   )r"   r$   rT   r.   ÚheadÚshaÚcontainsÚrÚholdersr_   Ú
rescue_refÚcounts   &&&         r   Ú_park_detached_headr{   p   sô  € õ /Ù�Ò7¸Ó=×HÑHÈAÔMÙÙ�GÒRÐTWÓX€DØ�;‰;×Ð˜"×
#Ñ
#Ó
%€CØ‡�˜!Ô§3ÙÙ˜ .°,ÀÐEZÐ![Ð]`Óa€HØ#Ÿ?™?×0Ð0¨b×7Ñ7Ô9ÓOÑ9�QÀ,Ñ=N�qˆqÑ9€GÐOØ×Ñ˜aÔ§GÙÜ�LŠLœÓ×&Ñ& Ó7€EØ7¸°x¸qÀÀÀqÈÈSÍÈ
ÐS€JÙ�˜,¨
Ð8¸#Ó>×IÑIÈQÔNÜÐ(¨¨S­¨
ð 3Ø�<˜xð)ô 	*äð Ø�u˜O¨C°­H¨:ð7ô 	8ä�_Ô%Ü�Š�ŒÙ�g 
¨I°s¸GÀ\ÐS[Ð]hÐiØóß!™6÷(ð (Ø%'¯©«ð 
ä	ˆF�5—?�?˜FÐ#Ð#jØˆLÐGÔHgÐGhÐhnðpô qä	Ð(¨¨Ð4VÐ
WÔXÜ˜g¨FÖ3ùò# Ps   Â#G.Â0G.c                ó2   € V ^8„  d   QhR\         R,          /# r:   ©r0   )r   s   "r   r   r   –   s   € ÷ ñ ´#¸µ*ñ r   c                óÀ  aa	a
€ ^ RI Hp ^ RIHo
  V '       d   \	        V 4      MR.oVe   TMV! 4       P
                  o	VV	V
3R lpV! RR4      V! RR4      rTVP                  P                  4       VP                  P                  4       rvVP                  ^ 8w  g"   VP                  ^ 8w  g   V'       d	   V'       g   R# VR8X  d   R	MT R
V 2#   \         d     R# i ; i)z·``"<branch> @ <short-sha>"`` for the checkout (``detached`` when not on a branch), or None. Never raises.

Appended to summary lines so a checkout parked on a stale branch is visible.)Ú_mr*   ÚgitNc                  ó*   <€ S! SR .V O3RS/\         B # )rk   r$   )Ú_GIT_TEXT_KW)r#   ÚcmdÚrootr+   s   *€€€r   Ú
_rev_parseÚ&_branch_head_label.<locals>._rev_parse    s"   ø€ Ù˜3 Ð 4¨tÐ 4ÑO¸$ÐOÄ,ÑOÐOr   z--abbrev-refrj   z--shortrI   z @ )
r3   r   r,   r+   r-   ÚPROJECT_ROOTr6   r7   r5   r4   )r"   r$   r   r…   rT   ru   Úbranch_nameÚsha_textrƒ   r„   r+   s   &&      @@@r   Ú_branch_head_labelrŠ   –   s¿   ú€ õ )Ý1ðß&Œd�7Œm¨U¨GˆØ’o‰s©2«4×+<Ñ+<ˆ÷	Pñ ! °Ó8¹*ÀYÐPVÓ:W�Ø &§¡× 3Ñ 3Ó 5°s·z±z×7GÑ7GÓ7I�XØ×Ñ Ô! S§^¡^°qÔ%8Ç×P[ÙØ +¨vÔ 5‘*¸;ÐGÀsÈ8È*ÐUÐUøÜô Úðús#   ‘C ™BC Â4C Â>C ÃCÃCc                ó$   € V ^8„  d   QhR\         /# r   r}   )r   s   "r   r   r   ¬   s   € ÷ *ñ *´3ñ *r   c                ó8   € \        W4      pV'       d   RV R2# R# )zC`` [<branch> @ <sha>]`` suffix for summary lines ("" when unknown).z [Ú]rc   )rŠ   )r"   r$   Úlabels   && r   Ú_branch_head_suffixr�   ¬   s!   € ä˜wÓ,€Eß!ˆR�ˆw�aˆ=Ð) rÐ)r   c                óŒ   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R\        \        \        3,          /# )r   r"   r$   Úcurrent_branchÚtarget_branchr   )r-   r0   r   Útupler   )r   s   "r   r   r   ²   sI   € ÷ 4Añ 4A¬$¬s­)ð 4A¼$ð 4AÔPSð 4AÔdgð 4AÔlqÔrvÔx{Ðr{Õl|ñ 4Ar   c                óÚ  € ^ RI Hp  ^ RIHp V! 4       ;'       g    / P	                  R/ 4      p\        V\        4      '       d$   \        VP	                  RR4      4      '       g   R# T! T R	R
.T4      pTP                  ^ 8w  d   R# TP                  P                  4       '       d   R# T! T RRRT R2.T4      p	T	P                  ^ 8w  g/   T	P                  P                  4       P                  4       '       g   R# \        T	P                  P                  4       4      p
T
^ 8X  d   R# T! T . ROT4      p\         ;QJ d4    R TP                  P#                  4        4       F  '       g   K   RM)	  RM%! R TP                  P#                  4        4       4      '       d   RRT
 23# T! T RRT 2.T/ \%        4       C\&        CR7      pTP                  ^ 8w  d   RRT
 23# TP                  P#                  4        Uu. uF  qÝP)                  R4      '       g   K  TNK  	  ppRT'       d   R\+        T4       23# R3#   \         d"   p\        P                  RT4        Rp?ELøRp?ii ; iu upi )uØ  Decide whether a parked feature branch may be auto-switched back to the update target.

- (True, "") â€” tree clean and every parked commit is in ``origin/<target>`` (no ``git cherry +``).
- (True, "unmerged:<n>") â€” tree clean but commits not in target; switching is safe (checkout keeps
  committed work) but caller must print a LOUD notice. Non-interactive callers (desktop, gateway
  /update, cron) can't resolve a skip, so a clean checkout must reach target.
- (False, "disabled"|"dirty"|"unverifiable") â€” caller must NOT touch the branch. Dirty is the
  genuinely unsafe case: uncommitted work riding an autostash across branches.
A config read failure must not disable the safety checks: fall through with the default.r2   )Úload_configÚupdatesÚauto_switch_parked_branchTFz4Could not read updates.auto_switch_parked_branch: %sNÚstatusz--porcelainrf   rg   zorigin/z..HEADrc   c              3   óp   "  € T F,  qP                  4       R,          P                  4       R8g  x € K.  	  R# 5i)é   ÚfalseNéÿÿÿÿ)rn   Úlower©Ú.0r[   s   & r   Ú	<genexpr>Ú/_assess_parked_branch_switch.<locals>.<genexpr>Ø   s)   é € Ð
XÑ;W°4�:‰:‹<˜Õ×!Ñ!Ó# wÖ.Ó;Wùs   ‚46z	unmerged:Úcherry)r(   Ú+)FÚdisabled)FÚunverifiable)FÚdirty)Trc   )Úconfigz--get-regexpz1^(remote\..*\.promisor|extensions\.partialclone)$)rJ   r.   Úhermes_cli.configr•   ÚgetÚ
isinstanceÚdictr   r4   ÚloggerÚdebugr5   r6   r7   ÚisdigitÚintÚanyrM   r   r
   Ú
startswithrQ   )r"   r$   r‘   r’   r.   r•   Ú_update_cfgÚexcr˜   ÚaheadÚahead_countÚpromisorr¢   r[   Úunmergeds   &&&&           r   Ú_assess_parked_branch_switchr¸   ²   s9  € õ 3ðRÝ1Ù"“}×*Ð*¨×/Ñ/°	¸2Ó>ˆÜ�k¤4×(Ò(´°k·o±oÐFaÐcgÓ6h×1iÒ1iØ$Ð$ñ �g ¨-Ð8¸#Ó>€FØ×Ñ˜AÔØ$Ð$Ø‡}�}×Ñ×ÒØÐñ �W˜z¨9¸À¸ÈfÐ6UÐVÐX[Ó\€EØ×Ñ˜1Ô E§L¡L×$6Ñ$6Ó$8×$@Ñ$@×$BÒ$BØ$Ð$Ü�e—l‘l×(Ñ(Ó*Ó+€KØ�aÔØˆñ ˜Ò!qÐsvÓw€Hß
ƒsÑ
X¸8¿?¹?×;UÑ;UÔ;WÓ
X‡s‡s‚sÑ
X¸8¿?¹?×;UÑ;UÔ;WÓ
X×XÒXØ�y  Ð.Ð.Ð.ñ
 �g ¨G°M°?Ð*CÐDÀcØKÔ3Ó5ÐKÔ9JÐKôM€Fà×Ñ˜AÔð �y  Ð.Ð.Ð.Ø!'§¡×!9Ñ!9Ô!;ÓTÑ!;˜¿¹Ès×?S—�Ñ!;€HÐTØ·�9œS ›]˜OÐ,Ð@Ð@¸bÐ@Ð@øôI ô RÜ�‰ÐKÈS×QÒQûðRüòF Us)   ˆH9 œAH9 Ç9I(ÈI(È9I%ÉI É I%r¦   z(the working tree has uncommitted changesr¤   z@updates.auto_switch_parked_branch is set to false in config.yamlc                ón   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R\        RR/# )r   r"   r$   r‘   r’   Úreasonr   N©r-   r0   r   )r   s   "r   r   r   ï   sB   € ÷ ñ ¬t´C­yð ¼tð ÔUXð Ôilð Ôvyð ð  Cñ r   c           
     ó®  € Rp\        \        4      ;_uu_ 4        \        V RRV 2R.V4      pV'       d   \        V4      pRRR4       \        P                  VRV 24      p\        R\         RV R24       \        R	V R
V R24       Ve   V^ 8”  d   \        RV RV R24       \        RV RV RV R\         24       R#   + '       g   i     L‹; i)zVLOUD block: why the update was skipped on a parked branch, behind-count, fix commands.Nrf   zHEAD..origin/rg   z6the branch state could not be verified against origin/Ú
u4   
âš  CODE UPDATE SKIPPED â€” checkout is parked on 'Ú'z  Not auto-switching to z: Ú.z  This checkout is z commit(s) BEHIND origin/u'    â€” the code you are running is stale.zG
  To resolve, inspect the branch and switch back yourself:
    git -C z status
    git -C z
 checkout z[ && hermes update
  (commit or stash your work on the branch first if you want to keep it)
)r   r4   r!   r¯   Ú_PARKED_SKIP_WHYr©   rp   Ú_BAR)r"   r$   r‘   r’   rº   ÚbehindÚbehind_textÚwhys   &&&&&   r   Ú!_print_parked_branch_skip_warningrÅ   ï   sõ   € à€FÜ	”)×	Õ	Ü! '¨J¸-ÈÀÐ8WÐYbÐ+cÐehÓiˆßÜ˜Ó%ˆF÷ 
ô ×
Ñ
˜vÐ)_Ð`mÐ_nÐ'oÓ
p€CÜ	ˆBŒtˆfÐIÈ.ÐIYÐYZÐ
[Ô\Ü	Ð$ ] O°2°c°U¸!Ð
<Ô=ØÒ˜f qœjÜÐ# F 8Ð+DÀ]ÀOÐSzÐ{Ô|Ü	ðØ�Uð Ø�U˜* ] Oð 4UÜUYÐTZð	\ö÷ 
×	ús   š'CÃC	c                ó@   € V ^8„  d   QhR\         R\         R\         RR/# )r   r‘   r’   Úunmerged_countr   Nr}   )r   s   "r   r   r     s*   € ÷ ñ ´Sð Ìð Ô^að Ðfjñ r   c                ó\   € \        R\         RV  RV RV RV RV  RV  R\         24       R# )	uÜ   LOUD notice when a clean parked branch with unmerged commits is auto-switched.

Non-interactive callers can't resolve a skip, so we proceed â€” but the unmerged work
(still safe on its branch) must be impossible to miss.r½   u   
âš  Checkout was parked on 'z' with z" commit(s) not merged into origin/z.
  Switching to u;    so the update can proceed â€” your commit(s) are safe on 'z7'.

  To pick the work back up later:
    git checkout N)rp   rÁ   )r‘   r’   rÇ   s   &&&r   Ú _print_parked_branch_kept_noticerÉ     s\   € ô
 
Ø
ŒTˆFð 'Ø'5Ð&6°gØÐ
Ð<¸]¸Oð LØ'˜ð )"Ø"0Ð!1ð 2?Ø?MÐ>NÈbÔQUÐPVð	Xör   ú0https://github.com/NousResearch/hermes-agent.gitz.skip_upstream_promptc                óh   € V ^8„  d   QhR\         \        ,          R\        R\        \        ,          /# ©r   r"   r$   r   )r-   r0   r   r	   )r   s   "r   r   r     s.   € ÷ Fñ FœT¤#�Yð F¬Tð F´h¼sµmñ Fr   c                ó    € \        V . ROV4      # )z5Get the URL of the origin remote, or None if not set.)Úremoteúget-urlÚoriginr    ©r"   r$   s   &&r   Ú_get_origin_urlrÒ     s   € ä�wÒ ?ÀÓEÐEr   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r   Ú
origin_urlr   )r	   r0   r   )r   s   "r   r   r   !  s"   € ÷ 	Yñ 	Yœ¤#�ð 	Y¬4ñ 	Yr   c                ót   € V '       g   R# R R lpV! V 4      \          Uu0 uF
  q!! V4      kK  	  up9  # u upi )zDCheck if the origin remote points to a fork (not the official repo).Fc                ó0   € V ^8„  d   QhR\         R\         /# )r   Úurlr   r}   )r   s   "r   r   Ú_is_fork.<locals>.__annotate__&  s   € ÷ (ñ (”3ð (œ3ñ (r   c                 óF   € V P                  R 4      p V P                  R4      # )Ú/ú.git)ÚrstripÚremovesuffix)r×   s   &r   Ú_normÚ_is_fork.<locals>._norm&  s    € Ø�j‰j˜‹oˆØ×Ñ Ó'Ð'r   )ÚOFFICIAL_REPO_URLS)rÔ   rÞ   Úofficials   &  r   Ú_is_forkrâ   !  s8   € çÙõ(ñ �ÓÕEWÓ$XÑEW¸ U¨8¦_ÑEWÑ$XÑXÐXùÒ$Xs    5c                óR   € V ^8„  d   QhR\         \        ,          R\        R\        /# rÌ   ©r-   r0   r   r   )r   s   "r   r   r   -  s*   € ÷ Dñ D¤$¤s¥)ð D´$ð D¼4ñ Dr   c                ó    € \        V . ROV4      # )z-Check if an 'upstream' remote already exists.)rÎ   rÏ   Úupstream©r&   rÑ   s   &&r   Ú_has_upstream_remoterè   -  s   € ä�7Ò=¸sÓCÐCr   c                óR   € V ^8„  d   QhR\         \        ,          R\        R\        /# rÌ   rä   )r   s   "r   r   r   2  s*   € ÷ Sñ S¤$¤s¥)ð S´$ð S¼4ñ Sr   c                ó,   € \        V RRR\        .V4      # )zHAdd the official repo as the 'upstream' remote. Returns True on success.rÎ   rR   ræ   )r&   ÚOFFICIAL_REPO_URLrÑ   s   &&r   Ú_add_upstream_remoterì   2  s   € ä�7˜X u¨jÔ:KÐLÈcÓRÐRr   c          
      ój   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R\        /# )r   r"   r$   Úbasert   r   )r-   r0   r   r¯   )r   s   "r   r   r   7  s4   € ÷ ñ ¤D¬¥Ið ´Dð Äð Ì3ð ÔSVñ r   c           
     óÌ   € \        \        4      ;_uu_ 4        \        V RRV RV 2.V4      pVe   \        V4      uuRRR4       #  RRR4       R#   + '       g   i     R# ; i)zDCount commits on `head` that are not on `base`. Returns -1 on error.rf   rg   z..Nrœ   )r   r4   r!   r¯   )r"   r$   rî   rt   rz   s   &&&& r   Ú_count_commits_betweenrð   7  sb   € ä	”)×	Õ	Ü˜G j°)À¸vÀRÈÀvÐ=NÐ%OÐQTÓUˆØÒÜ�u“:÷ 
Ò	à÷ 
ð €I÷	 
Ö	ð €Iús   ˜$AÁA#	c                ó$   € V ^8„  d   QhR\         /# r   r   )r   s   "r   r   r   @  s   € ÷ Dñ D¤dñ Dr   c                 óN   € ^ RI Hp  V ! 4       \        ,          P                  4       # )z2Check if user previously declined to add upstream.©Úget_hermes_home)Úhermes_constantsrô   ÚSKIP_UPSTREAM_PROMPT_FILEÚexistsró   s    r   Ú_should_skip_upstream_promptrø   @  s   € å0ÙÓÔ 9Õ9×AÑAÓCÐCr   c                 óº   € \        \        4      ;_uu_ 4        ^ RIHp  V ! 4       \        ,          P                  4        RRR4       R#   + '       g   i     R# ; i)z3Create marker file to skip future upstream prompts.ró   N)r   r4   rõ   rô   rö   Útouchró   s    r   Ú_mark_skip_upstream_promptrû   F  s4   € ä	”)×	Õ	Ý4Ù	Ó	Ô6Õ	6×=Ñ=Ô?÷ 
×	×	Ò	ús   ˜'A	Á	A	c                óR   € V ^8„  d   QhR\         \        ,          R\        R\        /# rÌ   rä   )r   s   "r   r   r   M  s*   € ÷ añ a¤d¬3¥ið a´dð a¼tñ ar   c                ó$   € \        V . ROVRR7      # )z9Push updated main to origin (sync fork); True on success.T)Únetwork)ÚpushrÐ   Úmainz--force-with-leaserç   rÑ   s   &&r   Ú_sync_fork_with_upstreamr  M  s   € ä�7ÒLÈcÐ[_Ô`Ð`r   c                ó^   € V ^8„  d   QhR\         \        ,          R\        R\        R\        /# ©r   r"   r$   Ú
assume_yesr   rä   )r   s   "r   r   r   R  s-   € ÷ ñ ¤D¬¥Ið ´Dð Ìð Ô\`ñ r   c               ó˜  € ^ RI HpHp \        R4       V'       gM   Vf]   \        P
                  P                  4       '       d%   \        P                  P                  4       '       g   \        R\         24       R# Ve'   V! RR4      P                  4       P                  4       pM( \        R4      P                  4       P                  4       pVR9  d   \        R\         R	24       V! 4        R# \        R
4       V! W4      '       g   \        R4       R# \        R4       R#   \        \        \        3 d    \        4        Rp Lzi ; i)zÔPrompt to add ``upstream`` and add it; False when the user declined, the run is non-interactive, or add failed.

``--yes`` means "don't block", not "mutate my remotes", so a non-interactive skip is NOT persisted.)rì   rû   u�   
â„¹ Your fork is not tracking the official Hermes repository.
  This means you may miss updates from NousResearch/hermes-agent.
zF  Skipping upstream setup (non-interactive run).
  Add it later with: Fz-Add official repo as 'upstream' remote? [y/N]Únz/Add official repo as 'upstream' remote? [Y/n]: z  Skipped. Run 'z' to add later.u   â†’ Adding upstream remote...u<     âœ— Failed to add upstream remote. Skipping upstream sync.uF     âœ“ Added upstream: https://github.com/NousResearch/hermes-agent.gitT>   rc   ÚyÚyes)r3   rì   rû   rp   rq   ÚstdinÚisattyr6   Ú_UPSTREAM_ADD_CMDr7   r�   ÚinputÚEOFErrorÚKeyboardInterruptÚUnicodeDecodeError)r"   r$   r  Úinput_fnrì   rû   Úresponses   &&$$   r   Ú_offer_upstream_remoter  R  s  € ÷ WÜ	ð	Nô÷ �hÒ&´·	±	×0@Ñ0@×0BÒ0BÄsÇzÁz×GXÑGX×GZÒGZÜÐWÔXiÐWjÐkÔlÙØÒÙÐKÈSÓQ×WÑWÓY×_Ñ_Óa‰ð	ÜÐNÓO×UÑUÓW×]Ñ]Ó_ˆHð Ð'Ô'ÜÐ Ô!2Ð 3°?ÐCÔDÙ"Ô$ÙÜ	Ð
)Ô*Ù ×-Ò-ÜÐLÔMÙÜ	Ð
RÔSÙøô Ô+Ô-?Ð@ô 	ÜŒGØŠHð	ús   Â''D$ Ä$"E	ÅE	c                   óB   a a€ ] tR tRt oRtV3R lV 3R lltRtVtV ;t# )ÚUpstreamTargetBrokenir  zXThe fork sync's upstream target fails the startup syntax check: refused before its move.c                ó0   <€ V ^8„  d   QhRS[ RS[ RS[ RR/# )r   ru   ÚpathÚerrorr   Nr}   )r   Ú__classdict__s   "€r   r   Ú!UpstreamTargetBroken.__annotate__u  s)   ø€ ÷ ;ñ ;™Cð ;¡sð ;±3ð ;¸4ñ ;r   c                ój   <€ \         SV `  R VR,           RV 24       WVuV n        V n        V n        R# )zupstream/main (ºNé
   Nz) has a syntax error in N)ÚsuperÚ__init__ru   r  r  )Úselfru   r  r  Ú	__class__s   &&&&€r   r  ÚUpstreamTargetBroken.__init__u  s6   ø€ Ü‰Ñ˜?¨3¨s­8¨*Ð4LÈTÈFÐSÔTØ*-°UÐ'ˆŒ�$”)˜TžZr   )r  r  ru   )	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r  Ú__static_attributes__Ú__classdictcell__Ú__classcell__)r   r  s   @@r   r  r  r  s   ù‡ € Ùb÷;÷ ;ó ;r   r  r  r  Úcheckout_movec                ó^   € V ^8„  d   QhR\         \        ,          R\        R\        R\        /# r  rä   )r   s   "r   r   r   z  s4   € ÷ \ñ \¬4´­9ð \¼4ð \ÔPTð \Ü9=ñ\r   c          	     óÞ  € ^ RI HpHpHpHp ^ RIHp	 ^ RIHp
 V! W4      '       g#   V! 4       '       g   \        WW#R7      '       g   R# \        R4        V
! V RRV	! RR	4      R
.3RVRRRR/V! 4       B  \        T . R.OT4      pT'       d   T! YTR4      MR/pT'       d   T! YRT4      MR/pT^ 8  g   T^ 8  d   \        R4       R# T^ 8”  d   \        RT R24       R# T^ 8X  d   \        R4       R# \        RT R24       ^ RIHp ^ RIHpHp \        T RR.T4      pT! T4      '       g   \        R4       R# Tp^ RI Hp TP)                  YTT4      ;p'       d   \+        T.TO5!  hTP-                  YTP/                  TT4      TTRR7      p T'       d   \        P                  ! ^RTR 7      hT;'       g    \0        ! T4      ;_uu_ 4        T
! T RR!T.3RTRR/T! 4       B  RRR4       T! T4      PC                  RR'7       \        T . R0OT4      ;pT8w  d=   TP9                  4        \        R(T;'       g    R)R*,           R+TR*,           R,24       R# \        R-4       R#   \        P                   d    \        R4        R# i ; i  + '       g   i     L®; i  \2        \        P4                  3 d²   pT'       g   TP7                  T4      '       d   TP9                  4        MTP;                  TT4       \        R"4       \=        TR#R4      ;'       g.    \?        T\        P                  4      '       d   R$M
\A        T4      ;p'       d   \        R%T R&24        Rp?R# Rp?ii ; i)1a¸  Offer to add ``upstream``, compare origin/main vs upstream/main, ff-pull when strictly behind, then push origin.

Returns True only when origin/main was actually verified against upstream/main; False when the check never
happened, so the caller never reports "up to date" on an origin-only compare. Fetches only upstream/main:
a bare fetch drags in thousands of auto-generated branches. ``UpstreamTargetBroken`` when the
upstream commit fails the startup syntax check: nothing moved, the caller rolls the update back.

``checkout_move(target)`` is the caller's context for the one tree write (the merge): the
paused gateways' tree gate is bound to *target* before git writes a file.

See #97052.
)rð   rè   Ú_no_prompt_git_kwargsrø   )Útracking_refspecr*   )r  r  Fu   
â†’ Fetching upstream...Úfetchræ   r   rm   r$   r   Tr'   u7     âœ— Failed to fetch upstream. Skipping upstream sync.rk   zrefs/remotes/origin/mainu9     âœ— Could not compare branches. Skipping upstream sync.u   
â„¹ Your fork has z— commit(s) not on upstream.
  Skipping upstream sync to preserve your changes.
  If you want to merge upstream changes, run:
    git pull upstream mainu&     âœ“ Fork is up to date with upstreamu   
â†’ Fork is u7    commit(s) behind upstream
â†’ Pulling from upstream...)Úupdate_cmd_commit)Úinterrupted_pull_markerÚis_object_idrj   u5     âœ— Could not resolve HEAD. Skipping upstream sync.)Ú_UPDATE_CRITICAL_FILESN)ÚpreÚtargetÚstashÚmerge©Ústderrz	--ff-onlyuO     âœ— Failed to pull from upstream. You may need to resolve conflicts manually.r9  rc   z    (Ú))Ú
missing_oku     âœ— HEAD is on Ú?r  z after the upstream merge, not r¿   u     âœ“ Updated from upstream©rk   ri   rl   z#refs/remotes/upstream/main^{commit}rœ   )rk   ri   rl   rj   )"r3   rð   rè   r-  rø   Úhermes_cli.update_cmd_checkr.  r,   r+   r  rp   Ú
subprocessÚCalledProcessErrorr!   Ú
hermes_clir0  Úhermes_cli._early_recoveryr1  r2  r3  Útarget_syntax_errorr  Úarm_commit_pointÚdebt_sha_for_moveÚ_no_moverK   ÚSubprocessErrorÚsettle_failed_tree_moveÚdisarm_commit_obligationsÚowe_restore_ofÚgetattrrª   r0   Úunlink)r"   r$   r  r  r*  rð   rè   r-  rø   r.  r+   ræ   Úorigin_aheadÚupstream_aheadÚ_commitr1  r2  r4  r5  r3  ÚbrokenÚrefusedr³   ÚdetailÚlandeds   &&$$$                    r   Ú_sync_with_upstream_if_neededrT  z  s~  € ÷ Hó  HÝ<Ý1Ù ×-Ò-Ù$×&Ò&Ô.DÀWÐ^h×.|Ó.|áÜ	Ð
&Ô'ðÙ�˜' :Ñ/?À
ÈFÓ/SÐU^Ð_ñ  	fÐehð  	fÐy}ð  	fð  FJð  	fñ  Ncó  Neò  	fô ˜7Ò$jÐloÓp€HßaiÑ)¨'¸ÐB\Ô]Ðoq€LßckÑ+¨GÐ:TÐV^Ô_Ðqs€NØ�aÔ˜>¨AÔ-ÜÐIÔJÙØ�aÔÜØ" < .ð 1Xð Xô	
ñ
 Ø˜ÔÜÐ6Ô7ÙÜ	ˆN˜>Ð*Ð*bÐ
cÔdõ 8ßPÜ
�g ¨VÐ4°cÓ
:€CÙ˜×ÒäÐEÔFÙØ€Fõ =Ø×,Ñ,¨W¸6ÐCYÓZÐZ€vÖZÜ" 6Ð3¨FÓ3Ð3Ø×&Ñ& w°W×5NÑ5NÈsÐTZÓ5[ÐadØ.4¸Dð 'ó B€Gð÷ Ü×/Ò/°°7À7ÔKÐKØ×'Ð'œxÐ'¨×2Õ2Ù�G˜g {°HÐ=ÑnÀ3ÐnÈdÐnÑVkÓVmÒn÷ 3ñ ˜CÓ ×'Ñ'°4Ð'Ô8Ü˜gÒ'NÐPSÓTÐTˆÐYaÔað 	×)Ñ)Ô+ÜÐ! 6§= =¨S°#Õ"6Ð!7Ð7VÐW_Ð`cÕWdÐVeÐefÐgÔhÙÜ	Ð
'Ô(áøôI ×(Ñ(ô ÜÐGÔHÚðú÷Z 3×2ûä”Z×/Ñ/Ð0ô ß�g×5Ñ5°c×:Ò:ð ×-Ñ-Õ/à×"Ñ" 3¨Ô,ÜÐ_Ô`Ü˜c 8¨TÓ2×zÐz¼ZÈÌZ×MjÑMj×=kÒ=k±rÔqtÐuxÓqyÐ{ˆ6Ö{Ü�E˜&˜ Ð#Ô$Ýûðúsa   Á I& Æ)J  Æ;J  ÇJÇ'J  É& J
Ê	J
ÊJ	ÊJ  ÊJ  Ê M,Ê;M'ËAM'Ì5M'ÍM'Í'M,c                óJ   € V ^8„  d   QhR\         \        ,          R\        RR/# )r   r"   r$   r   Nr»   )r   s   "r   r   r   Ù  s%   € ÷ 
ñ 
œt¤C�yð 
¬tð 
¸ñ 
r   c                ó4  € \        V RR.V4      p\        V . R	OV4      p\        V . R
OV4      pV'       d   W#8w  g   W$8X  d   R# V'       d   \        V RRWB.V4      '       g   R# \        R4       \        W4      '       d   \        R4       R# \        R4       R# )zòPublish an upstream sync to the fork's main once the update is validated.

Pushes only when local HEAD is upstream/main and strictly ahead of origin/main, i.e. this run
(or an earlier one whose push failed) fast-forwarded main from upstream.
rk   rj   Nz
merge-basez--is-ancestoru   â†’ Syncing fork...u     âœ“ Fork synced with upstreamu“     â„¹ Got updates from upstream but couldn't push to fork (no write access?)
    Your local repo is updated, but your fork on GitHub may be behind.r=  )rk   ri   rl   z!refs/remotes/origin/main^{commit})r!   r&   rp   r  )r"   r$   rt   ræ   rÐ   s   &&   r   Ú_push_synced_forkrW  Ù  s�   € ô �w ¨fÐ 5°sÓ;€Dä˜7Ò$jÐloÓp€HÜ˜Ò"fÐhkÓl€Fß�4Ô# t¤~Ùß”g˜g¨°oÀvÐ'TÐVY×ZÒZÙÜ	Ð
Ô Ü ×-Ò-ÜÐ/Ö0äðUö	
r   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r   r9  Úcodesr   )r0   r   )r   s   "r   r   r   ñ  s&   € ÷ bñ bœ3ð b¬ð b´ñ br   c                 óx   a € \         ;QJ d    V 3R  lV 4       F  '       g   K   R# 	  R# ! V 3R  lV 4       4      # )c              3   óT   <"  € T F  pR V 2S9   ;'       g	    RV 2S9   x € K  	  R# 5i)zHTTP zreturned error: Nr;   )rŸ   Úcoder9  s   & €r   r    Ú!_has_http_code.<locals>.<genexpr>ò  s7   øé € ÐaÑ[`ÐSW��t�fˆ~ Ñ'×NÐNÐ-=¸d¸VÐ+DÈÑ+NÔNÓ[`ùs   ƒ(—(TF)r°   )r9  rY  s   f*r   Ú_has_http_coder^  ñ  s.   ø€ ß‹3ÔaÑ[`Óa�3Œ3ÐaŠ3Ðaˆ3ÔaÑ[`ÓaÓaÐar   c                ó0   € V ^8„  d   QhR\         R\        /# )r   r„   r   )r   r0   )r   s   "r   r   r   õ  s   € ÷ 6ñ 6¤Dð 6¬Sñ 6r   c                óì   € \         P                  R8X  d0   R\        V 4      P                  RR4      ,           R,           pRV 2pM"R\        P
                  ! \        V 4      4       2pRV R,           RV 2# )	zªThe repair for a checkout git rejects: the installer pointed at THIS checkout (a bare one-liner
would rebuild the default directory and leave a ``--dir`` install broken).Úwin32r¾   z''z_& ([scriptblock]::Create((irm https://hermes-agent.nousresearch.com/install.ps1))) -InstallDir zOcurl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --dir uI   âœ— This Hermes checkout's git data is damaged (git no longer recognizes rÛ   z–), so it cannot be updated in place.
  Run the installer again to repair it; it moves the damaged checkout aside and keeps your config and chats:
    )rq   Úplatformr0   r   ÚshlexÚquote)r„   ÚquotedÚrepairs   &  r   Ú_damaged_checkout_messagerg  õ  sŠ   € ô ‡|�|�wÔØ”s˜4“y×(Ñ(¨¨dÓ3Õ3°cÕ9ˆð"Ø"( ð+‰ð cÔch×cnÒcnÔorÐswÓoxÓcyÐbzÐ{ˆØWÐX\Ð_eÕXeÐWfð g,ð -3¨8ð5ð 6r   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   r9  r„   r   )r0   r   r   )r   s   "r   r   r     s!   € ÷ 
 ñ 
 ¤cð 
 ¼$ð 
 Ä4ñ 
 r   c                ó"  € \         ;QJ d*    R V P                  4        4       F  '       g   K   RM	  RM! R V P                  4        4       4      '       g   R# \        VRR.VR7      pVP                  ^ 8g  ;'       g’    \        P
                  P                  \        P
                  P                  VP                  P                  4       4      4      \        P
                  P                  \        P
                  P                  V4      4      8g  # )a  The fetch failed because git cannot open *root* itself, not because of its remote.

git prints the same ``fatal: not a git repository`` for a remote whose ``.git`` is broken, so the
stderr line alone is not proof: the checkout must also fail to resolve as its own top level.
c              3   óB   "  € T F  qP                  R 4      x € K  	  R# 5i)zfatal: not a git repositoryN)r±   rž   s   & r   r    Ú,_checkout_rejected_by_git.<locals>.<genexpr>
  s   é € Ð^ÑJ]À$�‰Ð<×=Ð=ÓJ]ùs   ‚TFrk   z--show-toplevel©r$   )
r°   rM   r.   r5   Úosr  ÚnormcaseÚrealpathr6   r7   )r9  r"   r„   Útops   &&& r   Ú_checkout_rejected_by_gitrq    sÂ   € ÷ ‹3Ñ^È&×J[ÑJ[ÔJ]Ó^�3�3Š3Ñ^È&×J[ÑJ[ÔJ]Ó^×^Ò^ÙÜ
�7˜[Ð*;Ð<À$Ô
G€CØ�>‰>˜QÑ÷  ð  ¤"§'¡'×"2Ñ"2´2·7±7×3CÑ3CÀCÇJÁJ×DTÑDTÓDVÓ3WÓ"XÔ\^×\cÑ\c×\lÑ\lÜ
�‰×Ñ˜Óó] ñ # ð  r   c                 óP   € \        V R 4      ;'       g    RV P                  4       9   # )Ú429z
rate limit)r^  r�   ©Úss   &r   Ú<lambda>rv    s!   € Œ~˜a Ó'×DÐD¨<¸1¿7¹7»9Ñ+DÐDr   u_   âœ— GitHub is rate limiting requests or having an outage (HTTP 429) â€” try again in 5 minutes.c                 ó    € \        V R RRR4      # )Ú500Ú502Ú503Ú504)r^  rt  s   &r   rv  rv    s   € Œ~˜a ¨¨u°eÔ<r   uh   âœ— GitHub appears to be having an outage â€” try again in a few minutes (https://www.githubstatus.com).c                 ó&   € R V 9   ;'       g    RV 9   # )zCould not resolve hostzunable to accessr;   rt  s   &r   rv  rv    s   € Ð'¨1Ñ,×GÐGÐ0BÀaÑ0GÐGr   u9   âœ— Network error â€” cannot reach the remote repository.c                 ó&   € R V 9   ;'       g    RV 9   # )zcould not read Usernamezterminal prompts disabledr;   rt  s   &r   rv  rv    s   € Ð(¨AÑ-×QÐQÐ1LÐPQÑ1QÐQr   uÝ   âœ— GitHub rejected the anonymous fetch (asked for a login) â€” this usually means a GitHub outage; try again in a few minutes (https://www.githubstatus.com). If it persists, check `git remote -v` points at a public repo.c                 ó   € R V 9   # )zAuthentication failedr;   rt  s   &r   rv  rv     s
   € Ð&¨!Ò+r   uD   âœ— Authentication failed â€” check your git credentials or SSH key.c                 ó&   € R V 9   ;'       g    RV 9   # )zPermission denied (publickey)zHost key verification failedr;   rt  s   &r   rv  rv  '  s   € Ð.°!Ñ3×ZÐZÐ7UÐYZÑ7ZÐZr   u³   âœ— SSH authentication failed â€” check your SSH key is added to GitHub, or switch `origin` to HTTPS: `git remote set-url origin https://github.com/NousResearch/hermes-agent.git`.c                ó0   € V ^8„  d   QhR\         R\         /# )r   r9  r   r}   )r   s   "r   r   r   -  s   € ÷ Gñ G¤Cð G¬Cñ Gr   c                ó8   a € \        V 3R l\         4       R4      # )zUMap git-fetch stderr to a one-line diagnosis (caller also prints the raw first line).c              3   óL   <"  € T F  w  rV! S4      '       g   K  Vx € K  	  R # 5i©Nr;   )rŸ   ÚmatchesÚmessager9  s   &  €r   r    Ú*_classify_fetch_failure.<locals>.<genexpr>/  s   øé € ÐYÑ1EÑ-˜WÉÐQWÏ—’Ó1Eùs   ƒ$š
$u(   âœ— Failed to fetch updates from origin.)ÚnextÚ_FETCH_FAILURE_RULESr8  s   fr   Ú_classify_fetch_failurer‰  -  s"   ø€ äÔYÕ1EÓYð  \Fó  Gð  Gr   r"   r„   c                óJ   € V ^8„  d   QhR\         R\        \        ,          RR/# )r   r9  r„   r   N)r0   r	   r   )r   s   "r   r   r   2  s+   € ÷ Cñ C¤ð C¼XÄd½^ð CÐW[ñ Cr   c               ó®  € T ;'       g    RP                  4       p VRJ;'       d    \        W\        V4      4      p\        V'       d   \	        \        V4      4      M
\        V 4      4       V '       db   V P                  4       pVR,           F  p\        RV 24       K  	  \        V4      ^8”  d"   \        R\        V4      ^,
           R24       R# R# R# )zÔPrint the classified diagnosis plus bounded raw stderr for diagnosis. With *root*, a checkout
git rejects (no fetch can ever work; the ZIP fallback cannot tell user edits apart) gets the
installer repair instead.rc   NrB   z  z  ... (z more lines omitted))r7   rq  r   rp   rg  r‰  rM   rQ   )r9  r"   r„   ÚdamagedÚlinesr[   s   &$$   r   Ú_print_fetch_failurerŽ  2  s³   € ð �lˆl˜×!Ñ!Ó#€FØ˜$Ð×YÐYÔ#<¸VÌdÐSWËjÓ#Y€GÜ	·7Ô
#¤D¨£JÔ
/Ô@WÐX^Ó@_Ô`ßØ×!Ñ!Ó#ˆØ˜#—J�JˆDÜ�B�t�f�+Öñ äˆu‹:˜Œ?Ü�GœC ›J¨�OÐ,Ð,@ÐAÖBñ ñ	 r   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   Úargvr   )r-   r	   r   )r   s   "r   r   r   A  s"   € ÷ Rñ Rœ4ð R¤H¬T¥Nñ Rr   c                óÚ   €  ^ RI Hp V! V R.3R^/\        B pRTP                  ;'       g    RTP
                  ;'       g    R,           P                  4       9   #   \         d     R# i ; i)z]Run ``<argv> --version``; True/False = guard message seen/absent, None = probe itself failed.r*   z	--versionÚtimeoutNz	fork bombrc   )r,   r+   r‚   r4   r6   r9  r�   )r�  r+   r8   s   &  r   Ú_probe_fork_bombr“  A  si   € ðÝ5á˜ ˜}ÑI°bÐI¼LÑIˆð ˜FŸM™M×/Ð/¨R°F·M±M×4GÐ4GÀRÕH×OÑOÓQÑQÐQøô ô Úðús   ‚A ÁA*Á)A*c                ó0   € V ^8„  d   QhR\         R\        /# ©r   r"   r   )r-   r   )r   s   "r   r   r   L  s   € ÷ 
-ñ 
-¤ð 
-¬ñ 
-r   c                ó   € \        V 4      RJ # )aÑ  Whether *git_cmd* is a broken Git-for-Windows trampoline shim.

The ~46KB ``bin\git.exe``/``cmd\git.exe`` shims re-exec git-core; when they can't find it every call
dies with the launcher's guard message (a PATH problem, not network). Never raises; unknown states
report False so a probe failure can't block an update.

Git for Windows ships two ~46KB shims (``bin\git.exe``, ``cmd\git.exe``) that re-exec the real
``mingw64\libexec\git-core\git.exe``. See #87876.
T)r“  )r"   s   &r   Ú_git_is_trampoliner—  L  s   € ô ˜GÓ$¨Ð,Ð,r   c                ó$   € V ^8„  d   QhR\         /# r   ©r-   )r   s   "r   r   r   Y  s   € ÷ ñ ¤$ñ r   c                 ó*  € ^ RI Hp Hp . p\        \        4      ;_uu_ 4        Y ! 4       \        V! 4       4      3 Uu. uF'  q3R,          R,          R,          R,          R,          NK)  	  up,          pRRR4       V# u upi   + '       g   i     T# ; i)a–  PortableGit candidates: shared root first (where the managed tree actually lives, not the
profile-scoped HERMES_HOME), then profile home as a fallback for custom layouts.

The Hermes-managed PortableGit tree lives under the SHARED root (``<root>/git/...``), not the
profile-scoped HERMES_HOME (``<root>/profiles/<name>``), so a profile-scoped ``hermes update`` must look
there (monerostar review, #87876).
)Úget_default_hermes_rootrô   r€   Úmingw64Úlibexecúgit-coreúgit.exeN)rõ   r›  rô   r   r4   r   )r›  rô   Ú
candidatesr„   s       r   Ú_portable_git_candidatesr¡  Y  s¥   € ÷ JØ€JÜ	”)×	Õ	ØÐbyÓb{ô  ~Bñ  CRó  CTó  ~Uñ  bVó  Wñ  bVÐY]˜e•| iÕ/°)Õ;¸jÕHÈ9×TÐTñ  bVñ  Wõ  	Wˆ
÷ 
àÐùò W÷ 
Ö	àÐús   ¢B¼-A<
Á)	BÁ<BÂB	c                ó:   € V ^8„  d   QhR\         \        ,          /# r   )r	   r   )r   s   "r   r   r   h  s   € ÷ eñ eœ(¤4�.ñ er   c                 óä   € R U Uu. uF:  p R F1  p\        V 4      R,          V,          R,          R,          R,          NK3  	  K<  	  upp \        4       ,           p\        R V 4       R4      # u upp i )	u  Find a real Git-for-Windows ``git-core/git.exe`` (standard locations + managed PortableGit) that runs
without the trampoline guard. None when nothing suits â€” callers keep the broken command and let the
fetch-failure ZIP fallback handle it. A failed probe (None) disqualifies a candidate like a guard hit.

The trampoline symptom is PATH-level: ``bin\git.exe`` / ``cmd\git.exe`` (both ~46KB shims) fail to
re-exec git-core, while the real binary at ``mingw64\libexec\git-core\git.exe`` (â‰ˆ4.4MB) works when
invoked directly (#87876).
ÚGitr�  rž  rŸ  c              3   óŠ   "  € T F9  qP                  4       '       g   K  \        \        V4      .4      R J g   K5  Vx € K;  	  R# 5i)FN)r÷   r“  r0   )rŸ   Úcs   & r   r    Ú#_locate_real_git.<locals>.<genexpr>v  s.   é € Ð]™J�q¯(©(¯*”Ô9IÌ3ÈqË6È(Ó9SÐW\Ð9\—’›Jùs   ‚AžA¹
AN)zC:\Program FileszC:\Program Files (x86))Ú
clangarm64rœ  Úmingw32)r   r¡  r‡  )rî   Úarchr   s      r   Ú_locate_real_gitr«  h  sx   € ñ EôáDˆDÛ8ˆDô 	ˆT‹
�UÕ˜TÕ! IÕ-°
Õ:¸Y×FÐFá8ñ 	GÙDòô 	!Ó"õ	#€Jô
 Ñ]™JÓ]Ð_cÓdÐdùós   †A A,c                ó0   € V ^8„  d   QhR\         R\         /# r•  r™  )r   s   "r   r   r   y  s   € ÷ /ñ /¬ð /´ñ /r   c                óð   € ^ RI Hp \        P                  R8w  g   \	        V 4      '       g   V # V! 4       pVf   \        R4       V # \        RV 24       \        V4      .\        V R,          4      ,           # )zæSwap a broken Git-for-Windows trampoline for a real git binary so fetch/pull/checkout keep working;
if none is found leave the command untouched (fetch-failure handler falls back to ZIP). No-op off
Windows and when git is healthy.)r«  ra  uz   âš  Detected a broken git trampoline and could not locate a real git binary â€” the update will fall back to the ZIP path.u?   âš  Detected a broken git trampoline; switching to real git at :rš   NN)r3   r«  rq   rb  r—  rp   r0   r-   )r"   r«  Úreal_gits   &  r   Ú_ensure_non_trampoline_gitr¯  y  so   € õ 7Ü
‡|�|�wÔÔ&8¸×&AÒ&AØˆÙÓ!€HØÒÜð  Kô  	LØˆÜ	ÐKÈHÈ:Ð
VÔWÜ�‹Mˆ?œT '¨"¥+Ó.Õ.Ð.r   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# )r   Ú	repo_rootr   )r   rL   )r   s   "r   r   r   ˆ  s   € ÷ ñ ¤Dð ¬S´­Yñ r   c           	     ó�  € \        R4      0p ^ RIpVP                  V R,          P                  RR7      4      pVP	                  R. 4      p\        V\        4      '       d   VP	                  R. 4      p\        V\        4      '       g   V# V Fƒ  p\        \        4      ;_uu_ 4        V P                  \        V4      4       FB  pVR,          P                  4       '       g   K"  VP                  VP                  V 4      4       KD  	  RRR4       K…  	  V#   + '       g   i     Kš  ; i  \        \         \"        3 d     T# i ; i)a*  Manifest directories whose specs the single root ``package-lock.json`` records: the root plus every
workspace from the root ``workspaces`` globs (same model as ``update_cmd_deps._npm_manifest_paths``).
A manifest outside that graph (``website/``, ``scripts/whatsapp-bridge/``) has its own lockfile.r¿   Núpackage.jsonz	utf-8-sig)r   Ú
workspacesÚpackages)r   ÚjsonÚloadsÚ	read_textr©   rª   r«   r-   r   r4   Úglobr0   Úis_filerR   Úrelative_torK   rO   Ú	TypeError)r±  Úownersr¶  Úpackager´  ÚpatternÚ	directorys   &      r   Ú_npm_lockfile_ownersrÁ  ˆ  s
  € ô �3‹iˆ[€FðÛØ—*‘*˜i¨.Õ8×CÑCÈ[ÐCÓYÓZˆØ—[‘[ ¨rÓ2ˆ
Ü�j¤$×'Ò'Ø#Ÿ™¨
°BÓ7ˆJÜ˜*¤d×+Ò+ØˆMÛ!ˆGô œ)×$Õ$Ø!*§¡´°G³Ö!=�IØ! NÕ2×;Ñ;×=Ô=ØŸ
™
 9×#8Ñ#8¸Ó#CÖDñ ">÷ %Ñ$ñ "ð €M÷ %×$Ð$ûô ”Z¤Ð+ô ØØ€Mðús6   ŽA=D+ ÂD+ Â(8DÃ%$DÄ	D+ ÄD(Ä"	D+ Ä+EÅEc                 ó   € \        / 4      # )zNThe ``checkout_move`` of a run with no paused gateways: the step runs unbound.)r   )Ú_targetsÚ_bounds   *,r   rF  rF  ¡  s   € ä�r‹?Ðr   c          	     ó  € ^ RI Hp \        \        4      ;_uu_ 4        V! V RR.V4      pVP                  ^ 8w  d    RRR4       R# VP
                  P                  4        Uu. uF  qUP                  4       NK  	  ppV Uu0 uF0  qwP                  R4      '       g   K  \        V4      P                  kK2  	  pp\        \        V4      4      p	. p
V F•  pVP                  R4      '       g   K  \        V4      P                  pV\        R4      8H  ;'       d    \        W‰,          4      ;'       g    V\        R4      8g  ;'       d    WÈ9   pV'       d   K„  V
P                  V4       K—  	  V
'       g    RRR4       R# T;'       g    \        ! V
R7      ;_uu_ 4        V! V R	R
.V
OV4       RRR4       \        R\!        V
4       R24       RRR4       R# u upi u upi   + '       g   i     L<; i  + '       g   i     R# ; i)aÁ  Restore ``package-lock.json`` files npm rewrote non-deterministically, so the update sees a clean tree
instead of autostashing every run. A lockfile is kept when a manifest it records is dirty: for the root
lock that is the root or ANY workspace ``package.json`` (reverting it under a dirty ``apps/desktop``
manifest desyncs spec and lock and every later ``npm ci`` fails, #112378); a nested lock is kept only
with its sibling manifest. Best-effort.r2   Údiffú--name-onlyNr³  zpackage-lock.jsonr¿   ©ÚpathsÚcheckoutú--u"   â†’ Discarded npm lockfile churn (ú	 file(s)))rJ   r.   r   r4   r5   r6   rM   r7   Úendswithr   ÚparentrÁ  r   ÚappendrF  rp   rQ   )r"   r±  r*  r.   rÆ  r[   ÚchangedÚpÚdirty_manifestsÚroot_ownersr¦   r  Úlock_dirÚ	protecteds   &&$           r   Ú_discard_lockfile_churnrÖ  ¦  sŸ  € õ 3Ü	”)×	Õ	Ù˜ &¨-Ð!8¸)ÓDˆØ�?‰?˜aÔØ÷ 
Ñ	ð -1¯K©K×,BÑ,BÔ,DÓEÑ,D D—:‘:–<Ñ,DˆÐEÙ3:ÓY±7¨a¿j¹jÈ×>Xœ>œ4 ›7Ÿ>œ>±7ˆÐYÜ*¬4°	«?Ó;ˆØˆÛˆDØ—=‘=Ð!4×5Ò5ÙÜ˜D“z×(Ñ(ˆHØ!¤T¨#£YÑ.×VÐV´4¸Õ8UÓ3V÷ ð ØœD ›IÑ%×EÐE¨(Ñ*Eð ÷ ‘9Ø—‘˜TÖ"ñ ÷ Ø÷% 
Ñ	ð& ×'Ð'œxÐ'¨u×5Ö5Ù�W˜z¨4Ð8°%Ð8¸)ÔD÷ 6äÐ2´3°u³:°,¸iÐHÔI÷+ 
Ñ	ùò FùÚY÷ 6×5ú÷' 
×	Ð	úsx   žG2ÁG2Á#GÁ;G2ÂGÂGÂ7AG2ÄG2Ä0G2Å
G2ÅG2Å2G2Å=G2ÆG2ÆG	Æ+ G2Ç
G2ÇG/Ç*G2Ç2H	c               óä  aaaa€ ^ RI Hp ^ RIHo V RR.,           oVVV3R loV3R lp\	        \
        4      ;_uu_ 4        V! V . ROS4      P                  P                  4       P                  4       R8w  d    RRR4       R# V! 4       pVf    RRR4       R# V'       dˆ   T;'       g    \        ! \        V4      R	7      ;_uu_ 4        S! R
RRRRP                  \        V4      4      RR7       RRR4       V! 4       '       d    RRR4       R# \        R\        V4       R24       S! V . ROSRR\        4       R7       RRR4       R#   + '       g   i     Lb; i  + '       g   i     R# ; i)u‘  Take a managed checkout off ``core.autocrlf=true`` without leaving it dirty.

Git for Windows sets ``autocrlf=true`` system-wide, turning LF files CRLF and breaking ``git checkout``
on update; install.ps1 pins ``false`` but older checkouts never got it and only ``hermes update`` can
fix them. Pin and cleanup are one operation: under ``autocrlf=true`` a CRLF tree reads clean, so pinning
alone would expose every file as modified (whole-tree autostash). Pin only after the tree verifies clean
under it; a checkout we can't fully normalize is left as-is. Only ``true`` rewrites LF->CRLF
(unset/false/input leave the tree alone). Best-effort.

Checkouts created before that landed never got the pin and cannot receive it â€” the bootstrap installer
reuses its build-pinned ``install.ps1`` forever â€” so ``hermes update``, which ships with the checkout
itself, is the only path left that can fix them. See #67730.
r2   r*   ú-czcore.autocrlf=falsec                  ó:   <€ S! S\        V 4      3R S/\        BVB # rl  )r-   r‚   )r#   r%   Úprober±  r+   s   *,€€€r   Ú
_probe_runÚ*_normalize_managed_eol.<locals>._probe_runØ  s#   ø€ Ù�uœd 4›jÑN¨iÐN¼<ÐNÈ2ÑNÐNr   c                 ó´  <€ S! RRR4      p S! RRRRR4      pV P                   ^ 8w  g   VP                   ^ 8w  d   R# V P                  P                  R	4       Uu0 uF  q"'       g   K  VkK  	  upR
 VP                  P                  4        4        Uu0 uF/  p\	        V4      ^8X  g   K  V^,          '       g   K&  V^,          kK1  	  up,
          # u upi u upi )zDDirty paths whose ONLY change is CRLF; None when either probe fails.rÆ  z-zrÇ  rØ  zcore.quotepath=falsez	--numstatz--ignore-cr-at-eolNÚ c              3   ót   "  € T F.  qP                  4       '       g   K  VP                  R ^4      x € K0  	  R# 5i)Ú	N)r7   rn   rž   s   & r   r    Ú<_normalize_managed_eol.<locals>._eol_only.<locals>.<genexpr>æ  s,   é € ÐiÑ:X°$×\fÑ\f×\hÔ-˜$Ÿ*™* T¨1×-Ð-Ó:Xùs   ‚8ž8)r5   r6   rn   rM   rQ   )Ú	all_dirtyÚ
real_dirtyrÑ  ÚpartsrÛ  s       €r   Ú	_eol_onlyÚ)_normalize_managed_eol.<locals>._eol_onlyÛ  sÓ   ø€ á˜v t¨]Ó;ˆ	ñ   Ð&<¸fÀkÐSgÓhˆ
Ø×Ñ 1Ô$¨
×(=Ñ(=ÀÔ(BÙØ$×+Ñ+×1Ñ1°$Ô7Ó=Ñ7�a»1—�Ñ7Ñ=ái¸*×:KÑ:K×:VÑ:VÔ:XÔióA
ái�Ü�5‹z˜Q‰ô à#(¨§8¡8ô ˆE�!�HˆHÙiñA
õ 
ð 	
ùÒ=ùò A
s   Á	CÁ'CÂCÂ)CÂ:CÚtrueNrÈ  rÊ  z--pathspec-from-file=-z--pathspec-file-nulrË  rÞ  F)r  r'   u"   â†’ Normalized line-ending churn (rÌ  T)r$   r   r'   r   )r§   z--getúcore.autocrlf)r§   rè  r›   )rJ   r.   r,   r+   r   r4   r6   r7   r�   rF  rS   Újoinrp   rQ   r   )	r"   r±  r*  r.   rå  Úeol_onlyrÛ  rÚ  r+   s	   &f$   @@@r   Ú_normalize_managed_eolrë  Å  s5  û€ õ 3Ý1à�tÐ2Ð3Õ3€E÷Oõ
ô 
”)×	Õ	Ù�GÒAÀ9ÓM×TÑT×ZÑZÓ\×bÑbÓdÐhnÔnØ÷ 
Ñ	ñ “;ˆØÒØ÷ 
Ñ	÷ à×+Ð+¤8Ð+´6¸(Ó3C×DÖDÙ˜:Ð'?ÐAVÐX\Ø!%§¡¬6°(Ó+;Ó!<ÀEõK÷ Eñ �{Š{Ø÷ 
Ñ	ô Ð6´s¸8³}°oÀYÐOÔPÙ�Ò=À9Ð]aÐinÜ0Ó2õ	4÷ 
Ñ	÷ E×Dú÷ 
×	Ð	úsH   Á9EÂEÂEÂ"EÂ+EÃ
'E	Ã1EÄEÄ0EÅEÅEÅE/	zD====================================================================rƒ  )NN>   ú(git@github.com:NousResearch/hermes-agentú,git@github.com:NousResearch/hermes-agent.gitú,https://github.com/NousResearch/hermes-agentrÊ   )Ir&  Úloggingrm  rc  Ú
contextlibr   r   r?  rq   r   r   r   r   Úpathlibr   Útypingr	   Úhermes_cli._subprocess_compatr
   r   r   Úhermes_cli.update_cmd_commonr   Ú	getLoggerr¬   Ú_ORPHAN_RESCUE_REFS_TO_KEEPrs   r«   r‚   rÁ   r  r&   r.   r!   r`   r{   rŠ   r�   r¸   rÀ   rÅ   rÉ   rà   rë   rö   rÒ   râ   rè   rì   rð   rø   rû   r  r  r4   r  rT  rW  r^  rg  rq  rˆ  r‰  rŽ  r“  r—  r¡  r«  r¯  rÁ  rF  rÖ  rë  r;   r   r   Ú<module>r÷     s  ðñó Û 	Û ß ,Û Û 
ß 7Ó 7Ý Ý ç gÑ gÝ 5à	×	Ò	Ð2Ó	3€à Ð Ø"$Ð ñ
  4¨d¸WÈYÙ!3Ó!5ô7€à€Ø^Ð õ=ñ
¨uð ¸$õ õ*ð  ;ÐIh÷&>õR#4÷L÷,*õ4Aðp Ð7ØÐRðÐ õõ(òÐ ð GÐ Ø3Ð õFõ
	YõDõ
Sõ
õDò@õaõ
ô@;˜9ô ;ð\ÐW\ð \Ðgkð \Ø04÷\õ~
õ0bõ6õ
 ñ$ EØfðhá<ØoðqáGØ@ðBáQð1ð2ñ ,ØKðMñ [ðiðjð%Ð õ0Gð
C°ð CÈd÷ CõRõ
-õõeõ"/õò2ð
JÀô Jð>44Àö 44r   