+
    jHàj³“  ã            
       ó¦  € R t ^ RIt^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHtHt ^ RIHt ^ RIHtHtHtHtHt ^ RIHt ]P0                  ! R4      tRPt]! 0 RQm4      t]P:                  ! R	4      t0 RRmtR
RSRRTRRURRVRRW/t Rt!RR/R R llt"R R lt#RXR R llt$RRRR/R R llt%R R lt&R R lt'RYR! R" llt(R#RR$R R%R/R& R' llt)R(RZR)R/R* R+ llt*R, R- lt+RXR. R/ llt,R[R0 R1 llt-R2 R3 lt.R4 R5 lt/R6 R7 lt0R8 R9 lt1R: R; lt2R< R= lt3R> R? lt4RXR@ RA llt5R\RB RC llt6RD RE lt7RF RG lt8RXRH RI llt9RJRRKRRLRRMR/RN RO llt:R# )]aT  ZIP-download fallback for ``hermes update`` (Windows with broken git): two-phase stage/commit swap, dirty-tree guard.

Split out of ``update_cmd.py``; every name is re-imported there so ``hermes_cli.update_cmd.<name>`` keeps
resolving/monkeypatching. Origin helpers are imported lazily per function (no cycle; test patches stay effective).
N)Úsuppress)ÚPath)Ú
CollectionÚOptional)Ú_keep_aside)ÚZIP_SWAP_JOURNALÚrestore_interrupted_zip_swapÚwrite_zip_swap_journalÚzip_entry_identityÚzip_swap_owner_lock)Ú_record_stopzhermes_cli.update_cmdz+\.hermes-update-zip-swap\.[0-9a-f]{12}\.tmpÚappsÚ
hermes_cliÚscriptszui-tuiÚwebz;  Stash or commit your changes, then rerun `hermes update`.Úignore_errorsFc                ó4   € V ^8„  d   QhR\         R\        RR/# )é   Úpathr   ÚreturnN©ÚstrÚbool)Úformats   "Ú>/home/ubuntu/.hermes/hermes-agent/hermes_cli/update_cmd_zip.pyÚ__annotate__r   5   s!   € ÷ 	ñ 	”sð 	¬dð 	¸tñ 	ó    c               ó¦  € \         P                  P                  V 4      '       d   \        P                  ! V RR7       R# \         P                  P                  V 4      '       dY   V'       d9   \        \        4      ;_uu_ 4        \         P                  ! V 4       RRR4       R# \         P                  ! V 4       R# R#   + '       g   i     R# ; i)z0Remove a dir or file; missing paths are a no-op.T©r   N)	Úosr   ÚisdirÚshutilÚrmtreeÚexistsr   ÚOSErrorÚremove)r   r   s   &$r   Ú_remove_pathr&   5   ss   € ä	‡w�w‡}�}�T×ÒÜ�Š�d¨$×/Ü	�‰�‰˜×	Ò	ßÜœ'×"Õ"Ü—	’	˜$”÷ #Ñ"ô �IŠI�dŽOñ 
ç"×"Ð"ús   ÂB?Â?C	c                ó4   € V ^8„  d   QhR\         R\         RR/# )r   ÚsrcÚdstr   N©r   )r   s   "r   r   r   A   s&   € ÷ Gñ GœSð G¤sð G¨tñ Gr   c                ó4   € \        \        W4      V3.4       R# )uD  Replace *dst* with *src* without a half-deleted window (naive ``rmtree; copytree`` loses the old
tree when the copy fails partway â€” likely here, since the ZIP path only runs when file I/O is flaky).
Thin alias over the two-phase helpers; retained for the ``hermes_cli.main`` re-export surface.

The naive ``rmtree(dst); copytree(src, dst)`` has a destructive window: if the copy fails partway
(common on the Windows ZIP-update path, which only runs because file I/O is already flaky on that
machine), the old directory is already gone and nothing replaced it â€” the install is left with a deleted
tree (issue #49145, where ``ui-tui/`` vanished and broke the TUI).
Now a thin single-entry alias over the two-phase helpers below, which generalise the same
stage-then-swap discipline across every entry the ZIP update touches (#76104).
N)Ú_commit_staged_replacementsÚ_stage_replacement)r(   r)   s   &&r   Ú_atomic_replace_dirr.   A   s   € ô  Ô"4°SÓ">ÀÐ!DÐ EÖFr   c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r   r(   r)   r   r*   )r   s   "r   r   r   P   s!   € ÷ &ñ &œCð &¤cð &¼sñ &r   c                óÊ  € V R2pV R2p\         P                  P                  V4      '       g<   \         P                  P                  V4      '       d   \         P                  ! WA4       W43 FX  p\         P                  P                  V4      '       g   K*  \	        RV R\        \        V4      4      P                   R24       KZ  	  \         P                  P                  V 4      '       d   \         P                  ! V4       M\        W4       \        V4      p Ve	   V! V4       \        V4      V8w  d   \        RV R24      h\         P                  P                  V 4      '       d   \        P                  ! WR	R
7       V#   \         dQ    \!        \        4      ;_uu_ 4        \        T4      T8X  d   \#        T4       RRR4       h   + '       g   i     h ; ii ; i)a  Phase 1: copy *src* (dir or file) to a sibling staging path for *dst*; return it.
Touches nothing live, so a failure here leaves the install untouched. ``on_created(staging)`` runs
once the staging entry exists (a directory: before it is filled), so the journal can record it.ú.hermes-update-stagingú.hermes-update-oldu     âš  Kept z
 aside as z%: nothing proves it is this update's.Nzthe staging entry z( was replaced while it was being createdT)Údirs_exist_ok)r   r   ÚlexistsÚrenameÚprintr   r   Únamer    ÚmkdirÚ_copy_file_exclusiver
   r$   r!   ÚcopytreeÚBaseExceptionr   r&   )r(   r)   Ú
on_createdÚstagingÚbackupÚleftoverÚmades   &&&    r   r-   r-   P   s~  € ð �Ð+Ð,€GØˆuÐ&Ð'€Fô �7‰7�?‰?˜3×Ò¤B§G¡G§O¡O°F×$;Ò$;Ü
�	Š	�&Ôð Ó%ˆÜ�7‰7�?‰?˜8×$Ô$Ü�K ˜z¨´KÄÀXÃÓ4O×4TÑ4TÐ3Uð V#ð #ö $ñ &ô 
‡w�w‡}�}�S×ÒÜ
�Š�Õä˜SÔ*Ü˜gÓ&€DðØÒ!Ù�wÔÜ˜gÓ&¨$Ô.ÜÐ.¨w¨iÐ7_Ð`ÓaÐaÜ�7‰7�=‰=˜×ÒÜ�OŠO˜C¸Õ=ð €Nøô ô ô ”g×ÕÜ! 'Ó*¨dÔ2Ü˜WÔ%÷ ð 	÷ Öð 	úðús+   ÄAF Å-F Æ"G"Æ)GÇ	G"ÇGÇ	G"Úsyncr<   c                ó@   € V ^8„  d   QhR\         R\         R\        RR/# )r   r(   r)   rA   r   Nr   )r   s   "r   r   r   y   s)   € ÷ ñ œcð ¬ð ´dð ÐX\ñ r   c          	     óæ  € \         P                  \         P                  ,          \         P                  ,          \	        \         R^ 4      ,          \	        \         R^ 4      ,          p\         P
                  ! V 4      p\         P                  ! WR4      p Ve	   V! V4       \         P                  ! VR4      ;_uu_ 4       p\        V R4      ;_uu_ 4       p\        P                  ! W‡R	4       VP                  4        \         P                  \         P                  9   d7   \         P                  ! VP                  4       VP                  R,          4       \         P                  \         P                  9   d=   \         P                  ! VP                  4       VP                   VP"                  3R7       V'       d%   \         P$                  ! VP                  4       4       RRR4       RRR4       R#   + '       g   i     L; i  + '       g   i     R# ; i  \&         dL    \)        \*        4      ;_uu_ 4        \         P,                  ! T4       RRR4       h   + '       g   i     h ; ii ; i)
aƒ  ``copy2`` that only ever creates ``dst``: O_CREAT|O_EXCL (+O_NOFOLLOW) fails on any entry there
(symlink, hardlink, file) instead of writing through it, and the bytes and mode go through the held
fd. Times are copied only where that can be done without following ``dst``. ``on_created(dst)``
runs once ``dst`` exists, before a byte is written, so a journal can record what this run made.Ú
O_NOFOLLOWÚO_BINARYi€  NÚwbÚrbiÿ  )Únsé   )r   ÚO_WRONLYÚO_CREATÚO_EXCLÚgetattrÚstatÚopenÚfdopenr!   ÚcopyfileobjÚflushÚchmodÚsupports_fdÚfilenoÚst_modeÚutimeÚst_atime_nsÚst_mtime_nsÚfsyncr;   r   r$   r%   )	r(   r)   rA   r<   ÚflagsÚstÚfdÚoutÚsources	   &&$$     r   r9   r9   y   sm  € ô
 �K‰Kœ"Ÿ*™*Õ$¤r§y¡yÕ0´7¼2¸|ÈQÓ3OÕOÔRYÔZ\Ð^hÐjkÓRlÕl€EÜ	�Š�‹€BÜ	�Š�˜UÓ	#€BðØÒ!Ù�sŒOÜ�YŠY�r˜4× Ô  C¬¨c°4¯¬¸FÜ×Ò˜v¨GÔ4Ø�I‰IŒKÜ�x‰xœ2Ÿ>™>Ô)Ü—’˜Ÿ™› r§z¡z°FÕ':Ô;Ü�x‰xœ2Ÿ>™>Ô)Ü—’˜Ÿ™›¨2¯>©>¸2¿>¹>Ð*JÕKßÜ—’˜Ÿ™›Ô&÷ *9× Ñ ¯¯ú× × Ð ûô ô Ü”g×ÕÜ�IŠI�cŒN÷ à÷ Öàúðúsa   Â+H Ã HÃC'G3	Æ=$G3	Ç!HÇ)H Ç3HÇ>HÈH	ÈH ÈH È"I0È<IÉ	I0ÉI,É'	I0c                ó   € V ^8„  d   QhRR/# ©r   r   N© )r   s   "r   r   r   “   s   € ÷ Qñ Q˜tñ Qr   c                ó’   € V  F  w  r \        V4       K  	  R#   \         d"   p\        P                  RY4        Rp?K>  Rp?ii ; i)z¹Remove staging paths for never-committed entries; otherwise a phase-1 failure (disk exhaustion)
orphans up to a full second tree and the advised retry fails harder with less free space.z$could not remove staging path %s: %sN)r&   r$   ÚloggerÚwarning)Ústagedr=   Ú_dstÚexcs   &   r   Ú_discard_stagedri   “   sD   € ó  ‰ˆð	QÜ˜Ö!ó  øô ô 	QÜ�N‰NÐAÀ7×PÒPûð	Qús   ‰šA¥AÁAc                ó<   € V ^8„  d   QhR\         R\         R\        /# )r   r   r>   r   r   )r   s   "r   r   r   �   s!   € ÷ ñ œ3ð ¬ð ´ñ r   c                óX   €  \         P                  ! W4       R#   \         d     R# i ; i)z¦Hardlink ``path`` to ``backup``; False where links are unsupported. A link is all-or-nothing, so a
killed swap never leaves a short backup the restore would put back.FT)r   Úlinkr$   )r   r>   s   &&r   Ú_hardlink_backuprm   �   s,   € ðÜ
�Š�Ôñ øô ô Úðús   ‚ š)¨)Ú c                ó@   € V ^8„  d   QhR\         R\         R\         RR/# )r   r   r>   Útagr   Nr*   )r   s   "r   r   r   §   s(   € ÷ ñ ”sð ¤Cð ¬cð Èñ r   c                ó�  € \        W4      '       d   R# T RT;'       g%    \        P                  ! ^4      P                  4        R2p \	        WRVR7       \        P
                  ! WA4       R#   \         dL    \        \        4      ;_uu_ 4        \        P                  ! T4       RRR4       h   + '       g   i     h ; ii ; i)am  Back up the regular file ``path`` as a complete ``backup`` while ``path`` stays in place: a hardlink,
or where links are unsupported (FAT32/exFAT/SMB) a synced copy landed whole by ``os.replace``. The
copy's temp carries the journal's random ``tag``, and ``on_temp(temp)`` journals it as it comes into
existence: recovery deletes a temp only on that record (F78-R).NÚ.ú.tmpT)rA   r<   )	rm   r   ÚurandomÚhexr9   Úreplacer$   r   r%   )r   r>   rp   Úon_tempÚtmps   &&&& r   Ú_file_backupry   §   s”   € ô
 ˜×%Ò%ÙØˆH�A�c×0Ð0œRŸZšZ¨›]×.Ñ.Ó0Ð1°Ð
6€CðÜ˜T¨T¸gÕFÜ
�
Š
�3ÖøÜô Ü”g×ÕÜ�IŠI�cŒN÷ à÷ Öàúðús$   Á	$A/ Á/"CÂB1Â(	CÂ1CÂ<	CÚon_committedrp   rw   c                ó(   € V ^8„  d   QhR\         RR/# )r   rp   r   Nr*   )r   s   "r   r   r   ¸   s   € ÷ 45ñ 45Ä3ð 45Ð^bñ 45r   c               ó   € . p V  EF5  w  rVV R2p\         P                  P                  V4      '       d   \        V R24      h\         P                  P	                  V4      '       d\   \         P                  P                  V4      '       g7   \        WgW#4       VP                  Wg34       \         P                  ! WV4       K¾  \         P                  P                  V4      '       d*   \         P                  ! Wg4       VP                  Wg34       MVP                  VR34       \         P                  ! WV4       EK8  	  Te   T! 4        T F  w  r—T'       g   K  \        TRR7       K  	  R#   \         Ed    \        T4       Fñ  w  rg T'       dc   \         P                  P	                  T4      '       d>   \         P                  P                  T4      '       g   \         P                  ! Yv4       Kp  \        T4       T'       d@   \         P                  P                  T4      '       d   \         P                  ! Yv4       KÀ  KÂ  KÄ    \         d"   p\        P                  RYh4        Rp?Kë  Rp?ii ; i	  h i ; i)uÉ  Phase 2: swap every staged entry into place, rolling back all on failure.

Per-entry safety wasn't enough: a partway failure over ~90 entries left a mixed-version tree (every
file valid, combination unbootable). Covers plain files too (repo root holds 20 first-party modules).
Each swap is an ``os.rename`` onto a just-moved-aside path â€” atomic on POSIX and NTFS, unlike
``copy2`` onto a live path. Stage-all-then-swap-all shrinks the failure window to N renames and a
failed swap restores every entry already swapped, so the tree lands wholly new or wholly old.

``_atomic_replace_dir`` makes each *individual* directory swap safe, but the ZIP update replaces ~90
top-level entries in a loop, and nothing made the loop atomic *as a whole*. See #63717, #76091, #76104.

A plain file is never absent, not even for one rename: its backup is a hardlink (or, without
hardlinks, a complete copy) and ``os.replace`` lands the new bytes over it; only directories move
aside. The root modules every launcher imports first
(``hermes_constants``, ``hermes_bootstrap``) therefore always import, and ``hermes_bootstrap`` runs the
journal-driven restore even while a killed swap left a directory (``hermes_cli/`` included) moved aside.
r2   z1 appeared during the update; it was left in placern   zrollback failed for %s: %sNTr   )r   r   r4   ÚFileExistsErrorÚisfileÚislinkry   Úappendrv   r5   r$   Úreversedr&   rd   re   )
rf   rz   rp   rw   Úswappedr=   r)   r>   rh   rg   s
   &$$$      r   r,   r,   ¸   sÁ  € ð$ &(€GðÜ"‰LˆGØ�uÐ.Ð/ˆFÜ�w‰w�‰˜v×&Ò&Ü%¨¨Ð0aÐ&bÓcÐcÜ�w‰w�~‰~˜c×"Ò"¬2¯7©7¯>©>¸#×+>Ò+>Ü˜S¨#Ô7Ø—‘ ˜}Ô-Ü—
’
˜7Ô(ÙÜ�w‰w�‰˜s×#Ò#Ü—	’	˜#Ô&Ø—‘ ˜}Õ-à—‘  R˜yÔ)Ü�IŠI�g×#ñ #ð8 ÒÙŒÛ‰ˆß‰6Ü˜¨t×4ó  øô õ Ü# GÖ,‰KˆCð	GßœbŸg™gŸn™n¨V×4Ò4¼R¿W¹W¿^¹^ÈF×=SÒ=SÜ—J’J˜vÔ+ÙÜ˜SÔ!ßœbŸg™gŸo™o¨f×5Ò5Ü—I’I˜fÖ*ñ 6‘6øäô Gä—‘Ð;¸S×FÒFûðGúñ -ð 	ðúsh   „A$E/ Á)$E/ ÂAE/ Ã)AE/ Å/I=Æ,I
Æ9$I
ÇI
Ç4I=Ç67I
È.I
ÉI=É
I6ÉI1É+I=É1I6É6I=rf   Úshippedc          	      ó    € V ^8„  d   QhR\         R\        \        ,          R\        \        \        ,          ,          R\        \        ,          /# )r   Úrootrf   rƒ   r   )r   r   r   r   )r   s   "r   r   r   ï   sC   € ÷ 0\ñ 0\Ü
ð0\Ü%¤c�?ð0\Ü:BÄ:ÌcÅ?Õ:Sð0\äŒc…]ñ0\r   c          
     ó‚  aa€ V R,          P                  4       '       g   R# ^ RIHp \        P                  R8X  d   . ROMR.pV! V. ROV RRRRR	7      pVP
                  ^ 8X  d]   SfY   V! V. ROV RRRRR	7      pVP
                  ^ 8X  d$   \        VP                  P                  4       4      MRoVP
                  Vn        VP
                  ^ 8w  dc   VP                  ;'       g    VP                  ;'       g    R
P                  4       P                  4       pRV'       d   RV^ ,           R2 2# R
 2# \        ;QJ dB    VV3R lVP                  ;'       g    R
P                  4        4       F  '       g   K   RM7	  RM3! VV3R lVP                  ;'       g    R
P                  4        4       4      pV'       d   R# R# )a  Why overlaying a ZIP onto ``root`` would destroy work, or None if safe.

The swap replaces every top-level entry (minus a tiny preserve set) and deletes backups, so uncommitted
edits and untracked files are gone. Fails closed when git status cannot run. ``staged`` is for the
pre-swap re-check: phase 1 leaves ``<entry>.hermes-update-staging`` for those entries, which git
reports as untracked; without the filter the re-check always refuses. ``shipped`` is the extracted
ZIP's top-level entry set once known (the re-check); before the download the tracked root entries stand
in for it. A gitignored path under a root entry the ZIP does not ship is never touched by the swap.

Fail closed when git status cannot run: unknown dirtiness is not a license to clobber the tree (#87304).
ú.gitN)Úrun_gitÚwin32ÚgitTzutf-8rv   )ÚcwdÚcapture_outputÚtextÚencodingÚerrorsrn   z could not check the working treez (Ú)c              3   ó¨   <"  € T FG  pVP                  4       ;'       d+    \        VS4      '       * ;'       d    \        VS4      '       * x € KI  	  R # 5i©N)ÚstripÚ#_is_zip_preserved_entry_status_lineÚ$_is_zip_staging_artifact_status_line)Ú.0Úlinerƒ   rf   s   & €€r   Ú	<genexpr>Ú,_zip_overlay_block_reason.<locals>.<genexpr>  sZ   øé € ð ñ 7ˆDð 	�
‰
‹÷ 	Cð 	CÜ3°D¸'ÓBÔB÷	Cð 	Cä4°T¸6ÓBÔBô	Có 7ùs   ƒAŸA¸AFz;the working tree has uncommitted changes or untracked files)rŠ   z-czwindows.appendAtomically=false)Ústatusz--porcelainz--untracked-files=allz--ignored=matching)zls-treez--name-onlyÚHEAD)r#   Úhermes_cli.update_custodyrˆ   ÚsysÚplatformÚ
returncodeÚsetÚstdoutÚ
splitlinesÚstderrr“   Úany)	r…   rf   rƒ   rˆ   Úgit_cmdÚresultÚtrackedÚdetailÚdirtys	   &dd      r   Ú_zip_overlay_block_reasonrª   ï   s�  ù€ ð �6�M×!Ñ!×#Ò#ÙÝ1äADÇÁÐQXÔAXÓ=Ð_dÐ^e€GÙð 	ÒYØ ¨D¸7È9ô€Fð ×Ñ˜AÔ '¢/ñ ØÒ7Ø T°¸wÈyô
ˆð 7>×6HÑ6HÈAÔ6M”#�g—n‘n×/Ñ/Ó1Ô2ÐSWˆØ#×.Ñ.ˆÔØ×Ñ˜AÔØ—-‘-×6Ð6 6§=¡=×6Ð6°B×=Ñ=Ó?×JÑJÓLˆØ1Çv°B°v¸aµy°kÀÐ2CÐ1VÐWÐWÐSUÐ1VÐWÐW÷ ‹Cõ ð —]‘]×(Ð( b×4Ñ4Ô6ó	�C�CŠCõ ð —]‘]×(Ð( b×4Ñ4Ô6ó	ó €E÷ MRÐHÐ[ÐW[Ð[r   c                ó0   € V ^8„  d   QhR\         R\         /# )r   r   r   r*   )r   s   "r   r   r   "  s   € ÷ Sñ SœCð S¤Cñ Sr   c                 ó¬   € V P                  4       P                  R 4      P                  RR4      P                  R4      P                  R^4      ^ ,          # )Ú"Ú\Ú/)r“   rv   ÚrstripÚsplit)r   s   &r   Ú_status_top_levelr²   "  sD   € Ø�:‰:‹<×Ñ˜cÓ"×*Ñ*¨4°Ó5×<Ñ<¸SÓA×GÑGÈÈQÓOÐPQÕRÐRr   c                óh   € V ^8„  d   QhR\         R\        \        \         ,          ,          R\        /# )r   r—   rƒ   r   )r   r   r   r   )r   s   "r   r   r   &  s1   € ÷ hñ h¬cð h¼HÄZÔPSÅ_Õ<Uð hÔaeñ hr   c                óB  a€ \        V 4      ^8¼  d   V R,          V R,          3MRV 3w  r#\        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   VP                  R4      MV.p\        ;QJ d    R V 4       F  '       d   K   RM	  RM! R V 4       4      '       d   R# VR	8w  d   R# VP	                  4       P	                  R
4      P                  RR4      P                  R4      pVP                  R4      w  rgoVe	   Wa9  d   R# VP                  R^4      R,          R9   ;'       gc    \        ;QJ d3    V3R l\        P                  VR4       4       F  '       g   K   R# 	  R# ! V3R l\        P                  VR4       4       4      # )uÅ  True when the swap would not destroy what a porcelain status line names: every path sits under a
preserved top-level entry; or the line is gitignored (``!!``) and under a root entry the ZIP does not
ship (``.bytecode-fingerprint``, ``.hermes-bootstrap-complete``, ``hermes_agent.egg-info/`` â€” the swap
replaces ``shipped`` entries only); or a ``!!`` build output nested under a shipped dir that the swap
keeps (`_ZIP_PRESERVED_NESTED`) or regenerates (``__pycache__``, ``node_modules``). Every real install
has all of these, and blocking on them made the ZIP fallback refuse every install. Tracked edits,
renames and other untracked/ignored user files still block.

The ``" -> "`` split applies ONLY to R/C codes: porcelain v1 doesn't quote plain names with spaces, so
``venv -> node_modules`` on a ``!!``/``??`` line is ONE path and splitting would fail-open. Requiring
EVERY path preserved keeps renames out of a preserved dir (``R venv/x -> src/x``) blocking.
:Nr   Nºé   NNrn   c              3   ó*   "  € T F	  qR 9   x € K  	  R# 5i)ÚRCNrb   )r–   Úcodes   & r   r˜   Ú6_is_zip_preserved_entry_status_line.<locals>.<genexpr>4  s   é € Ð(IÁ&¸$°®Ã&ùó   ‚TFz -> c              3   óF   "  € T F  p\        V4      \        9   x € K  	  R # 5ir’   )r²   Ú_ZIP_PRESERVED_TOP_LEVEL)r–   r   s   & r   r˜   rº   5  s   é € Ð
QÉ5À4Ô˜TÓ"Ô&>Ö>Ë5ùs   ‚!z!!r­   r®   r¯   c              3   óf   <"  € T F&  pSV8H  ;'       g    SP                  V R 24      x € K(  	  R# 5i)r¯   N)Ú
startswith)r–   ÚkeepÚnesteds   & €r   r˜   rº   =  s7   øé € ð MhÙDf¸Dˆ�$‰×7Ð7˜&×+Ñ+¨t¨f°A¨JÓ7Ô7ÓDfùs   ƒ1”1éÿÿÿÿ)Ú__pycache__Únode_modulesrb   )Úlenr¤   r±   Úallr“   rv   r°   Ú	partitionÚrsplitÚ_ZIP_PRESERVED_NESTEDÚget)	r—   rƒ   rš   ÚpayloadÚpathsr   ÚtopÚ_rÁ   s	   &&      @r   r”   r”   &  sb  ø€ ô /2°$«i¸1¬n�t˜B•x  b¥Ñ*À2ÀtÀ*�O€Fß%(£SÑ(IÁ&Ó(I§S§S¢SÑ(IÁ&Ó(I×%IÒ%IˆG�M‰M˜&Ô!ÐPWÈy€Eß
ƒsÑ
QÉ5Ó
Q‡s‡s‚sÑ
QÉ5Ó
Q×QÒQÙØ�„~ÙØ�=‰=‹?× Ñ  Ó%×-Ñ-¨d°CÓ8×?Ñ?ÀÓD€DØ—^‘^ CÓ(�N€CˆFØÒ˜sÔ1ÙØ�;‰;�s˜AÓ˜rÕ"Ð&EÑE÷ hð hÏËô MhÜDY×D]ÑD]Ð^aÐceÔDfóMhÏÌð hÊð hÈô MhÜDY×D]ÑD]Ð^aÐceÔDfóMhó Jhð hr   c                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# )r   r—   rf   r   )r   r   r   )r   s   "r   r   r   A  s+   € ÷ Uñ U¬sð U¼JÄs½Oð UÔUYñ Ur   c                ó  € \        \        V 4      ^8¼  d
   V R,          MT 4      pV\        9   ;'       gL    \        \        P                  V4      4      ;'       g&    Y! Uu0 uF  q3\        ^ ,          ,           kK  	  up9   # u upi )a  True when a porcelain status line is Hermes' own: a root breadcrumb, or the staging copy of an
entry this run staged. Any other ``*.hermes-update-staging``/``-old`` may be a user's file (a manual
``cp -r tools tools.hermes-update-old``) that staging would delete, so it blocks.rµ   )r²   rÅ   Ú_ZIP_HERMES_ROOT_ARTIFACTSr   Ú_ZIP_JOURNAL_TEMPÚ	fullmatchÚ_ZIP_STAGING_ARTIFACT_SUFFIXES)r—   rf   rÍ   Úitems   &&  r   r•   r•   A  s   € ô ¬¨D«	°Q¬˜D žH¸DÓ
A€CØÔ-Ñ-÷ Tð T´Ô6G×6QÑ6QÐRUÓ6VÓ1W÷ Tð TØÈFÓSÉFÀDÔ<¸QÕ?×?Ð?ÉFÑSÑSðUùÚSs   Á Bc                ó   € V ^8„  d   QhRR/# ra   rb   )r   s   "r   r   r   J  s   € ÷ ñ ¨ñ r   c                 óD  € ^ RI Hp  \        V ! 4       P                  4       \	        V ! 4       P                  4      pVf   R# \        RV R24       \        R4       \        \        4       \        R4       \        R4       V ! 4       P                  P                  ^4       R# )z@Refuse to overlay a ZIP onto a dirty git checkout.

See #87304.
©Ú_mNu   âœ— ZIP fallback refused: rr   z^  Overlaying the ZIP would overwrite uncommitted edits and permanently delete untracked files.z$  To inspect: git status --porcelainÚlocal_changes_blocked)
Úhermes_cli.update_cmdrÙ   r   ÚPROJECT_ROOTrª   r6   Ú_STASH_HINTr   r�   Úexit)rÙ   Úreasons     r   Ú_abort_zip_update_if_dirty_treerà   J  sz   € õ
 )ô !¡£×!2Ñ!2Ô3Ü&¡r£t×'8Ñ'8Ó9€FØ‚~ÙÜ	Ð& v h¨aÐ
0Ô1Ü	Ð
jÔkÜ	Œ+ÔÜ	Ð
0Ô1ÜÐ(Ô)ÙƒD‡H�H‡M�M�!Ör   c                ó4   € V ^8„  d   QhR\         R\         RR/# )r   Úzip_pathÚtmp_dirr   Nr*   )r   s   "r   r   r   ^  s!   € ÷ ñ ¤#ð ´ð ¸ñ r   c           	     óÂ  € ^ RI p^ RIpVP                  V R4      ;_uu_ 4       p\        P                  P                  V4      pVP                  4        FÛ  p\        P                  P                  \        P                  P                  WP                  4      4      pVP                  V\        P                  ,           4      '       g    Wu8w  d   \        RVP                   R24      hVP                  VP                  ^,	          R,          4      '       g   KÅ  \        RVP                   24      h	  VP                  V4       RRR4       R#   + '       g   i     R# ; i)z¤Extract, rejecting zip-slip AND symlink members: a source ZIP never legitimately contains
symlinks, and a compromised mirror could use them to plant files anywhere.NÚrzZip-slip detected: z escapes extraction directoryi ð  z)ZIP contains unsupported symlink member: )rN   ÚzipfileÚZipFiler   r   ÚrealpathÚinfolistÚjoinÚfilenamer¿   ÚsepÚ
ValueErrorÚS_ISLNKÚexternal_attrÚ
extractall)râ   rã   Ú_statræ   ÚzfÚtmp_dir_realÚmemberÚmember_paths   &&      r   Ú_extract_zip_safelyrö   ^  sô   € ó ÛØ	�‰˜ 3×	'Ô	'¨2Ü—w‘w×'Ñ'¨Ó0ˆØ—k‘k–mˆFÜŸ'™'×*Ñ*¬2¯7©7¯<©<¸ÇÁÓ+QÓRˆKØ×)Ñ)¨,¼¿¹Õ*?×@Ò@À[ÔE`Ü Ð#6°v·±Ð6GÐGdÐ!eÓfÐfà�}‰}˜f×2Ñ2°bÕ8¸HÕD×EÔEÜ Ð#LÈVÏ_É_ÐL]Ð!^Ó_Ð_ñ $ð 	�‰�gÔ÷ 
(×	'×	'Ò	'ús   £C0EÄ+EÅE	c                óF   € V ^8„  d   QhR\         R\        \         ,          /# )r   râ   r   ©r   r   )r   s   "r   r   r   o  s"   € ÷ Gñ Gœcð G¤h¬s¥mñ Gr   c                ó
  € ^ RI pVP                  V 4      ;_uu_ 4       pVP                  P                  RR4      P	                  4       pRRR4       \
        P                  ! RX4      '       d   V# R#   + '       g   i     L1; i)zXThe commit a GitHub archive was made from: ``git archive`` stores it as the ZIP comment.NÚasciirv   ú[0-9a-f]{40})ræ   rç   ÚcommentÚdecoder“   ÚrerÓ   )râ   ræ   rò   rü   s   &   r   Ú_archive_commitrÿ   o  s^   € ãØ	�‰˜×	"Ô	" bØ—*‘*×#Ñ# G¨YÓ7×=Ñ=Ó?ˆ÷ 
#ä—l’l ?°G×<Ò<ˆ7ÐFÀ$ÐF÷ 
#×	"ús   ž+A2Á2B	c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r   rã   Úbranchr   r*   )r   s   "r   r   r   w  s!   € ÷ ñ œSð ¬#ð ´#ñ r   c                ór  € \         P                  P                  V RV 24      p\         P                  P                  V4      '       go   \         P                  ! V 4       FT  p\         P                  P                  W4      p\         P                  P                  V4      '       g   KI  VR8w  g   KR  Vu # 	  V# )z_GitHub ZIPs extract to ``hermes-agent-<branch>/``; fall back to the first non-``__MACOSX`` dir.úhermes-agent-Ú__MACOSX)r   r   rê   r    Úlistdir)rã   r  Ú	extractedÚdÚ	candidates   &&   r   Ú_extracted_rootr	  w  s|   € ä—‘—‘˜W¨°f°XÐ&>Ó?€IÜ�7‰7�=‰=˜×#Ò#Ü—’˜GÖ$ˆAÜŸ™Ÿ™ WÓ0ˆIÜ�w‰w�}‰}˜Y×'Ô'¨A°®OØ Ò ñ %ð Ðr   c                óV   € V ^8„  d   QhR\         R\        \         ,          R\         RR/# )r   r  ÚentriesÚproject_rootr   N)r   Úlist)r   s   "r   r   r   ‚  s-   € ÷ 
ñ 
¤cð 
´D¼µIð 
ÌSð 
ÐUYñ 
r   c                ó  a € \        V 3R lV 4       4      \        V 3R lV 4       4      ,           p\        VR,          4      p\        P                  ! V4      P                  pWT8  d!   \        RVR,           RVR,           R24      hR# )	u¿   Staging costs one extra tree copy; swaps are renames, so require the copy plus 20% headroom â€” not 2x,
which would block updates on exactly the space-constrained machines that hit this path.c           	   3   ó*  <"  € T Fˆ  p\         P                  ! \         P                  P                  SV4      4       FM  w  r#pV FA  p\         P                  P	                  \         P                  P                  W%4      4      x € KC  	  KO  	  KŠ  	  R # 5ir’   )r   Úwalkr   rê   Úgetsize)r–   ÚentryÚdirpathÚ_dirsÚfilesÚfr  s   &     €r   r˜   Ú)_require_staging_space.<locals>.<genexpr>…  sp   øé € ð ñ ˆEÜ%'§W¢W¬R¯W©W¯\©\¸)ÀUÓ-KÖ%LÑ!ˆG˜EÛˆAô 	�‰�‰œŸ™Ÿ™ WÓ0×1Ð1ñ ñ 	2á%Lñ 	2Ûùs   ƒBBc              3   ó(  <"  € T F‡  p\         P                  P                  \         P                  P                  SV4      4      '       g   KH  \         P                  P	                  \         P                  P                  SV4      4      x € K‰  	  R # 5ir’   )r   r   r~   rê   r  )r–   Úer  s   & €r   r˜   r  ‘  sX   øé € ÐwÁ¸AÌBÏGÉGÏNÉNÔ[]×[bÑ[b×[gÑ[gÐhqÐstÓ[u×LvÔ7ŒB�G‰G�O‰OœBŸG™GŸL™L¨°AÓ6×7Ð7Ãùs   ƒABÁABg333333ó?z=not enough free disk space to stage the update safely (need ~z
 MB, have z MB)NrI   )ÚsumÚintr!   Ú
disk_usageÚfreeÚRuntimeError)r  r  r  ÚneedÚrequiredr  s   f&&   r   Ú_require_staging_spacer!  ‚  s•   ø€ ô ô ñ óó ô 	ÔwÁÓwÓwõx€Dô �4˜#•:‹€HÜ×Ò˜\Ó*×/Ñ/€DØ„ÜðØ ;Õ/Ð0°
¸4ÀKÕ;PÐ:QÐQUðWó
ð 	
ñ r   c                ó4   € V ^8„  d   QhR\         R\         RR/# )r   r_   Údestinationr   Nr*   )r   s   "r   r   r   ›  s!   € ÷ *ñ *¤3ð *´Sð *¸Tñ *r   c                ó„   €  \         P                  ! W4       R#   \         d    \        P                  ! Y4        R# i ; i)zïHardlink where the filesystem allows (apps/desktop/node_modules is hundreds of MB, and a link stays
valid after the swap unlinks the old tree; on Windows a link also succeeds on a locked Hermes.exe
where copy2 raises); byte copy otherwise.N)r   rl   r$   r!   Úcopy2)r_   r#  s   &&r   Ú_link_or_copy_artifactr&  ›  s.   € ð*Ü
�Š�Ö$øÜô *Ü�Š�V×)ð*ús   ‚ š!?¾?c                ó@   € V ^8„  d   QhR\         R\         R\         RR/# )r   rÕ   Úliver=   r   Nr*   )r   s   "r   r   r   ¥  s.   € ÷ 	bñ 	b¤#ð 	b¬Sð 	b¼3ð 	bÀ4ñ 	br   c                óD  € \         P                  V R4       EF  p\        P                  P                  ! V.VP                  R4      O5!  p\        P                  P                  ! V.VP                  R4      O5!  p\        P                  P                  V4      '       g&   \        P                  P                  V4      '       g   K²  \        P                  ! \        P                  P                  V4      RR7       \        P                  ! WER\        R7       EK  	  R# )z°Clone the live build outputs under *item* into its staged copy so the swap keeps them.
A path the ZIP ships wins over the live copy; a never-built install has nothing to graft.r¯   T)Úexist_ok)ÚsymlinksÚcopy_functionNrb   )rÉ   rÊ   r   r   rê   r±   r4   r    ÚmakedirsÚdirnamer!   r:   r&  )rÕ   r(  r=   rÁ   r_   r#  s   &&&   r   Ú_graft_nested_artifactsr/  ¥  s²   € ô (×+Ñ+¨D°"×5ˆÜ—‘—’˜dÐ7 V§\¡\°#Ó%6Ó7ˆÜ—g‘g—l’l 7Ð?¨V¯\©\¸#Ó->Ó?ˆÜ�7‰7�?‰?˜;×'Ò'¬r¯w©w¯}©}¸V×/DÒ/DÙÜ
�Š”B—G‘G—O‘O KÓ0¸4Õ@Ü�Š˜°dÔJ`×aÐaó 6r   c                ó–   € V ^8„  d   QhR\         R\        \         ,          R\         R\        \        \         \         3,          ,          /# )r   r  r  r  r   )r   r  Útuple)r   s   "r   r   r   ±  s:   € ÷ ñ œcð ¬D´­Ið ÄSð Ü'+¬E´#´s°(­OÕ'<ñr   c           
     ón  a€ . p \        V4       F†  w  rV\        P                  P                  W&4      pTP	                  \        \        P                  P                  W4      TSf   RMV3V3R ll4      V34       \        WgVR,          ^ ,          4       Kˆ  	  V#   \         d    \        T4       h i ; i)aÚ  Phase 1 for every entry; on failure nothing is live yet, so drop partial staging copies so a retry
starts from the same free space. An entry is listed only once its staging copy is this run's: a copy
that fails partway drops its own partial tree (``_stage_replacement``), and a pathname this run never
created (a user's file there) is never ``_discard_staged``'s to delete (F78).
``on_created(index, staging)``: the journal's hook as each staging entry comes into existence.Nc                 ó   <€ S! W4      # r’   rb   )r   Úir<   s   &&€r   Ú<lambda>Ú _stage_entries.<locals>.<lambda>¾  s   ø€ ÁzÐRSÔGZr   rÂ   )	Ú	enumerater   r   rê   r€   r-   r/  Ú	Exceptionri   )r  r  r  r<   rf   ÚindexrÕ   r)   s   &&&f    r   Ú_stage_entriesr:  ±  s§   ø€ ð %'€FðÜ$ WÖ-‰KˆEÜ—'‘'—,‘,˜|Ó2ˆCØ�M‰MÔ-Ü—‘—‘˜YÓ-¨sØ"Ò*‘ÀÖ1Zó]à^aðcô dô $ D¨v°b­z¸!­}Ö=ñ .ð €Møô ô Ü˜ÔØðús   …BB ÂB4c                óJ   € V ^8„  d   QhR\         R\        \        ,          RR/# )r   r…   r  r   N)r   r  r   )r   s   "r   r   r   É  s&   € ÷ 6ñ 6¤ð 6´´Sµ	ð 6Ðdhñ 6r   c                óJ  a a€ V Uau. uFI  o\         ;QJ d     VV 3R lV 4       F  '       g   K   RM	  RM! VV 3R lV 4       4      '       g   KG  SNKK  	  ppV'       d!   \        RRP                  V4       R24       R# S \        ,          P	                  RR7       R# u upi )	zÁThe journal is the only record of the swap's siblings (``<entry><suffix>``): it goes only once
every one of them is gone, else the next launch's recovery could not tell them from a user's file.c              3   ó¬   <"  € T FI  p\         P                  P                  \         P                  P                  SSV,           4      4      x € KK  	  R # 5ir’   ©r   r   r4   rê   )r–   ÚxrÕ   r…   s   & €€r   r˜   Ú)_drop_journal_if_clean.<locals>.<genexpr>Ì  s8   øé € Ð+lÑckÐ^_¬B¯G©G¯O©O¼B¿G¹G¿L¹LÈÈtÐVWÍxÓ<X×,YÐ,YÓckùó   ƒAATFu2     âš  Could not remove the update's own copies of z, z(; the next `hermes` launch removes them.N)Ú
missing_ok)r¤   r6   rê   r   Úunlink)r…   r  ÚsuffixesrÕ   Úlefts   f&&` r   Ú_drop_journal_if_cleanrF  É  s€   ù€ ñ %Ôm™W�T¯«Õ+lÑckÓ+l¯¯ªÕ+lÑckÓ+l×(l�DˆD™W€DÐmßÜÐBÀ4Ç9Á9ÈTÃ?ÐBSð Tð ô 	áØ	ÔÕ×$Ñ$°Ð$Ö5ùò ns   ˆB ˜B °B ÁB c                ó^   € V ^8„  d   QhR\         R\        \         ,          R\        R\        /# )r   r  r  r…   r   )r   r  r   )r   s   "r   r   r   Ô  s3   € ÷ Pñ P¬ð P´t¼Cµyð PÌð PÔ]añ Pr   c                óò  a aaaaaa€ ^ RI Hp ^ RIHpHp \        S4       S\        ,          P                  4       '       d   \        R4      h\        SRR7      ;_uu_ 4       pV'       g1   \        VP                  R8X  d   R4      hRVP                   R	24      hS Uau. uFC  oS\        ;QJ d     VV3R
 lR! 4       F  '       g   K   RM	  RM! VV3R
 lR! 4       4      RR.NKE  	  upo\        P                  ! ^4      P                  4       o\        SRSS4       R VV VVV3R llp	 \!        S S\#        S4      V	4      p
\)        SSSR7      pTel   \+        T
4       \'        SS4       \-        RT R24       \-        R4       \-        \.        4       \1        R4       T! 4       P2                  P5                  ^4       TP7                  \9        S 4      T4      ;p'       d   \;        T^ ,           RT^,           24      hTP=                  ST;'       g    R4       S F  p\?        ST^ ,          ,          4      T^&   K!  	  \        SRSS4       / oR TTTT3R llp\A        T
TTT3R lSTR7       \C        \D        4      ;_uu_ 4        \'        SSRRRS R 234       RRR4       RRR4       T
# u upi   \$         d    \'        SS4       h i ; i  + '       g   i     L;; i  + '       g   i     X
# ; i)"z»Stage + swap under the ZIP swap journal and its owner lock (``_early_recovery``), so a kill at
any point is finished or rolled back by the next launch and no staging/backup sibling leaks.©Úupdate_cmd_commit)Ú_UPDATE_CRITICAL_FILESrÙ   zEan interrupted ZIP update could not be settled; see the warning aboveg      $@)ÚwaitÚbusyz:another `hermes update` is swapping this install right nowzno ZIP swap lock, no swap (r�   c              3   ó¬   <"  € T FI  p\         P                  P                  \         P                  P                  SSV,           4      4      x € KK  	  R # 5ir’   r>  )r–   ÚsuffixrÕ   r…   s   & €€r   r˜   Ú,_journaled_stage_and_swap.<locals>.<genexpr>ç  s=   øé € ð &PÙ4N¨&ô ')§g¡g§o¡o´b·g±g·l±lÀ4ÈÐPVÍÓ6W×&XÐ&XÛ4NùrA  rn   r2   TFr=   c                ó4   € V ^8„  d   QhR\         R\        RR/# )r   r9  r=   r   N)r  r   )r   s   "r   r   Ú/_journaled_stage_and_swap.<locals>.__annotate__ì  s&   € ÷ 	Nñ 	N¤ð 	N¬sð 	N°tñ 	Nr   c                 ó  <€ \        V4      SV ,          ^&   V \        S4      ^,
          8X  gK   \        P                  P	                  \        P                  P                  SSV ,          4      4      '       d   \        SRSS4       R# R# )r   r=   N)r
   rÅ   r   r   r    rê   r	   )r9  r=   r  r  ÚgenÚjournal_entriesr…   s   &&€€€€€r   Úrecord_stagedÚ0_journaled_stage_and_swap.<locals>.record_stagedì  sf   ø€ ô
 );¸7Ó(CˆO˜EÕ" 1Ñ%Øœ˜G› qÕ(Ô(¬B¯G©G¯M©M¼"¿'¹'¿,¹,ÀyÐRYÐZ_ÕR`Ó:a×,bÒ,bÜ& t¨Y¸ÈÖMñ -cr   )rf   rƒ   Nu*   âœ— ZIP fallback aborted before the swap: rr   zi  Files appeared in the checkout while the update was downloading; committing the swap would delete them.rÚ   z: Úswappingc                ó(   € V ^8„  d   QhR\         RR/# )r   rx   r   Nr*   )r   s   "r   r   rR    s   € ÷ 	Rñ 	RœSð 	R Tñ 	Rr   c                 ó€   <€ \        V R R7      S\        P                  P                  V 4      &   \	        SRSSS4       R# )T)ÚfillingrX  N)r
   r   r   Úbasenamer	   )rx   rT  rU  r…   Útempss   &€€€€r   Úrecord_tempÚ._journaled_stage_and_swap.<locals>.record_temp  s3   ø€ Ü+=¸cÈ4Ô+PˆE”"—'‘'×"Ñ" 3Ó'Ñ(Ü" 4¨°_ÀcÈ5ÖQr   c                  ó    <€ \        SR SS 4      # )Ú	committed)r	   )rT  rU  r…   s   €€€r   r5  Ú+_journaled_stage_and_swap.<locals>.<lambda>  s   ø€ Ô)?ÀÀkÐSbÐdgÔ)hr   )rz   rp   rw   r1   z.hermes-update-old.rs   )rn   r2   )#r   rJ  rÛ   rK  rÙ   r   r   r#   r  r   rß   r¤   r   rt   ru   r	   r:  r   r;   rF  rª   ri   r6   rÝ   r   r�   rÞ   Útree_syntax_errorr   ÚSyntaxErrorÚarm_commit_obligationsr
   r,   r   r$   )r  r  r…   Ú
target_shaÚ_commitrK  rÙ   ÚownedrÕ   rV  rf   Úrecheck_reasonÚbrokenr  r^  rT  rU  r]  s   fff&    `      @@@r   Ú_journaled_stage_and_swaprk  Ô  sÉ  þ€ õ 8ß@ô ! Ô&ØÔÕ×'Ñ'×)Ò)ÜÐbÓcÐcÜ	˜T¨×	-Õ	-°ßÜØ"'§,¡,°&Ô"8ð  \ó mð mØ@[Ð\a×\hÑ\hÐ[iÐijÐ>kómð mñ fmônÙelÐ]að !§#£#õ &PÙ4Nó&P§#§#¢#õ &PÙ4Nó&Pó #PØQSÐUWóYÙelñnˆä�jŠj˜‹m×ÑÓ!ˆÜ˜t Y°ÀÔE÷	Nô 	Nð	Ü# I¨w¼¸D»	À=ÓQˆFô 3°4ÀÐQXÔYˆØÒ%Ü˜FÔ#Ü" 4¨Ô1ÜÐ>¸~Ð>NÈaÐPÔQÜÐ}Ô~Ü”+ÔÜÐ0Ô1Ù‹D�H‰H�M‰M˜!Ôð ×.Ñ.¬t°I«Ð@VÓWÐWˆ6ÖWÜ ¨¥ ¨2¨f°Q­i¨[Ð9Ó:Ð:à×&Ñ& t¨Z×-=Ð-=¸2Ô>Û$ˆEÜ)¨$°°qµ­/Ó:ˆE�!‹Hñ %ä˜t Z°À#ÔFØ "ˆ÷	Ró 	Rô 	$ØÖ!hÐnqØõ	!ô ”g×ÕÜ" 4¨Ð3KÐMaØ5HÈÈÈTÐ3Rð3Tô U÷ ÷E 
.ðJ €Mùò{nøô  ô 	Ü" 4¨Ô1Øð	ú÷T ×ú÷E 
.Ö	-ðJ €Músc   Á">K%Â J1Â1J1Ã	 J1Ã)AK%Ä,J6ÅCK%ÈA4K%Ê
K	ÊK%Ê1K%Ê6KËK%ËK"ËK%Ë%K6	c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   rh   Ú
downloadedr   )r;   r   r   )r   s   "r   r   r   '  s!   € ÷ 	=ñ 	=œð 	=´tð 	=Äñ 	=r   c               óú   € ^ RI p\        V RR4      VP                  8X  g7   \        V \        4      '       d#   \        V 4      P                  R4      '       d   R# \        V \        4      '       d   R# V'       d   R# R# )zWClosed stop token for a failed ZIP update: by exception type and errno, never its text.NÚerrnoznot enough free disk spaceÚ	disk_fullÚtarget_syntax_errorÚ
zip_failedÚdownload_failed)ro  rM   ÚENOSPCÚ
isinstancer  r   r¿   rd  )rh   rm  ro  s   &$ r   Ú_zip_stop_classrv  '  s]   € ãäˆs�G˜TÓ" e§l¡lÔ2Ü�sœL×)Ò)¬c°#«h×.AÑ.AÐB^×._Ò._ÙÜ�#”{×#Ò#Ù$ß%ˆ<Ð<Ð+<Ð<r   c          	      ól   € V ^8„  d   QhR\         R\         R\         R,          R\        \         ,          /# )r   r  Úzip_urlrf  Nr   rø   )r   s   "r   r   r   3  s3   € ÷ 13ñ 13¤3ð 13´ð 13Ä#ÈÅ*ð 13ÔX`ÔadÕXeñ 13r   c                ó`  € ^ RI Hp ^ RIp^ RIHp \        R4       VP                  RR7      pRp \        P                  P                  VRV  R	24      pV! W4       R
p\        R4       \        W†4       \        V4      p	V	e   V'       d-   W’8w  d'   \        RT	;'       g    R RT;'       g    R R24      hT	p\        W`4      p
\        P                  ! V
4       Uu. uF  q»\        9  g   K  VNK  	  pp\!        V! 4       P"                  4      p\%        W¬V4       \'        W¬\)        V4      V4      p\        R\+        V4       R24       V\,        P.                  ! VR
R7       # u upi   \0         Ed   p\3        \0        4      ;_uu_ 4        \5        T! 4       P"                  4       \)        T! 4       P"                  4      \6        ,          P9                  4       '       g   ^ RIHp TP?                  4        RRR4       M  + '       g   i     M; i\        RT 24       \        R4       \        R4       \A        \C        Y÷R7      4       T! 4       PD                  PG                  ^4        Rp?MRp?ii ; i \,        P.                  ! TR
R7       R#   \,        P.                  ! TR
R7       i ; i)uè  Download the source ZIP for *branch* and two-phase swap it into the checkout; return the commit it
installed: the archive's own, which must equal ``target_sha`` when one is pinned.
``sys.exit(1)`` on any failure; the install ends fully updated or fully rolled back.
Two-phase: stage every entry (dirs AND top-level files) beside its target, then swap all in with
same-filesystem renames, rolling back on failure â€” one-at-a-time replacement left a mixed, unbootable
tree on interruption.rØ   N)Úurlretrieveu!   â†’ Downloading latest version...zhermes-update-)ÚprefixFr  ú.zipTu   â†’ Extracting...zthe archive names commit Únonez, not za full commit SHAz(; refusing to install unidentified bytesu   âœ“ Updated z items from ZIPr   rI  u   âœ— ZIP update failed: z*  Your existing install was left in place.zq  Re-run `hermes update` to retry; if the agent won't start, reinstall from https://hermes-agent.nousresearch.com)rm  )$rÛ   rÙ   ÚtempfileÚurllib.requestrz  r6   Úmkdtempr   r   rê   rö   rÿ   rí   r	  r  r½   r   rÜ   r!  rk  r   rÅ   r!   r"   r8  r   r   r   r#   r   rJ  Údisarm_commit_obligationsr   rv  r�   rÞ   )r  rx  rf  rÙ   r~  rz  rã   rm  râ   Úarchivedr  r4  r  r  rf   r  rg  s   &&&              r   Ú_download_and_swap_ziprƒ  3  s2  € õ )ãÝ*Ü	Ð
-Ô.Ø×ÑÐ&6ÐÓ7€GØ€Jð#3Ü—7‘7—<‘< ¨=¸¸ÀÐ)EÓFˆÙ�GÔ&Øˆ
ÜÐ!Ô"Ü˜HÔ.ô # 8Ó,ˆØÒ§
¨xÔ/EÜÐ8¸×9KÐ9KÀVÐ8LÈFØ *× AÐ AÐ.AÐBÐBjðló mð màˆ
Ü# GÓ4ˆ	Ü Ÿjšj¨Ô3ÓYÑ3˜Ô@XÑ7X—1�1Ñ3ˆÐYÜ™2›4×,Ñ,Ó-ˆÜ˜y°<Ô@Ü*¨9¼tÀLÓ?QÐS]Ó^ˆÜ�œS ›[˜M¨Ð9Ô:Øô  	�Š�g¨TÖ2ùò+ Zøô õ ô ”i× Õ Ü(©«×):Ñ):Ô;Ü™›×*Ñ*Ó+Ô.>Õ>×FÑF×HÒHÝCØ×1Ñ1Ô3÷	 !× × Ð úô
 	Ð'¨ sÐ+Ô,äÐ:Ô;Üð  Bô  	CÜ”_ QÔ>Ô?Ù
‹�‰�‰�a×Ñûðúð 	ä�Š�g¨T×2øŒ�Š�g¨TÖ2úso   ±AE) ÂE) Â!E) Â./E) ÃE$Ã.E$Ã4AE) Å$E) Å)I5Å5I0ÆA*G?Ç6	I0Ç?HÈ
A!I0É+J É0I5É5J ÊJ-Úhad_desktop_app_before_updaterf  Útarget_repositoryÚcompletion_requestc                ód   € V ^8„  d   QhR\         R\        R,          R\        R,          R\         /# )r   r„  rf  Nr…  r   )r   r   )r   s   "r   r   r   h  s3   € ÷ %ñ %¼Dð %Ü" T�zð%ÜEHÈ4ÅZð%ä/3ñ%r   c               ó  € ^ RI HpHp V! 4       P                  V 4      pVR8w  dJ   \	        RV R24       \	        RV R24       \        R4       V! 4       P                  P                  ^4       \        4        Vf   ^ RI	H
p V! R	R
7       Ve)   \        P                  ! RV4      '       g   \        R4      hVe   TMRV 2p	T;'       g    Rp
\        P                  ! RV
4      '       dY   \        ;QJ d+    R V
P                  R4       4       F  '       g   K   R	M 	  RM! R V
P                  R4       4       4      '       d   \        R4      h\!        VRV
 RV	 R2V4      pT;'       g    TVR&   RVR&   V! V4       R	# )z¤Update via ZIP when Windows git file I/O fails; dependency/build failures propagate.

A supplied commit keeps the archive on the target selected before Git failed.
)rÙ   Ú_complete_source_updateÚmainu   âœ— --branch=z: is not supported on the Windows ZIP-fallback update path.z¾  This path runs when git file I/O is broken on the system. Either resolve the git-side breakage (typically an antivirus or NTFS filter holding files open) and rerun `hermes update --branch z/`, or update against main with `hermes update`.Úbranch_unsupported)Ústop_for_relaunchT)Ú
incompleterû   z,ZIP update requires an exact full commit SHAzrefs/heads/zNousResearch/hermes-agentz[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+c              3   ó*   "  € T F	  qR9   x € K  	  R# 5i)rr   N)rr   z..rb   )r–   Úparts   & r   r˜   Ú"_update_via_zip.<locals>.<genexpr>‡  s   é € ÐIÑ3H¨4˜;Ö&Ó3Hùr»   r¯   Fz-ZIP update requires a GitHub owner/repositoryzhttps://github.com/z	/archive/r|  Úexpected_shaÚzipÚ
apply_mode)rÛ   rÙ   r‰  Ú_resolve_update_branchr6   r   r�   rÞ   rà   Úhermes_cli._old_updaterrŒ  rþ   rÓ   rí   r¤   r±   rƒ  )Úargsr„  rf  r…  r†  rÙ   r‰  r  rŒ  ÚrefÚ
repositoryÚ	installeds   &$$$$       r   Ú_update_via_ziprš  h  sl  € ÷ Bñ ‹T×(Ñ(¨Ó.€FØ�ÔÜ�˜f˜XÐ%_Ð`ÔaÜðð �xÐNðPô	
ô 	Ð)Ô*Ù
‹�‰�‰�aÔÜ#Ô%àÒ!Ý=Ù TÕ*ØÒ¤b§l¢l°?ÀJ×&OÒ&OÜÐGÓHÐHØ"Ò.‰*°kÀ&ÀÐ4J€CØ"×AÐAÐ&A€JÜ�LŠLÐ;¸Z×HÒHß‹sÑI°:×3CÑ3CÀCÔ3HÓI�s�sŠsÑI°:×3CÑ3CÀCÔ3HÓI×IÒIÜÐHÓIÐIÜ& vÐ1DÀZÀLÐPYÐZ]ÐY^Ð^bÐ/cÐeoÓp€IØ)2×)@Ð)@°jÐ�~Ñ&Ø',Ð�|Ñ$ÙÐ.Ô/Ùr   )r1   r2   >   ú.update-incompleteú.hermes-update-zip-swapú.lazy-refresh-incompleteú.hermes-update-zip-swap.lock>   ÚvenvrÄ   ú.envr‡   ú.venv)zdesktop/releasezdesktop/distzdesktop/node_moduleszdesktop/build)Úweb_dist)zwhatsapp-bridge/node_modules)ÚdistrÄ   zpackages/hermes-ink/dist)rÄ   r’   )rn   Nrb   )rb   ))r1   );Ú__doc__ÚloggingÚ
contextlibr   r   rþ   r!   Ú
subprocessr�   Úpathlibr   Útypingr   r   Úhermes_cli._early_recoveryr   Úhermes_cli._early_recovery_zipr   r   r	   r
   r   Úhermes_cli.update_cmd_commonr   Ú	getLoggerrd   rÔ   Ú	frozensetrÑ   ÚcompilerÒ   r½   rÉ   rÝ   r&   r.   r-   r9   ri   rm   ry   r,   rª   r²   r”   r•   rà   rö   rÿ   r	  r!  r&  r/  r:  rF  rk  rv  rƒ  rš  rb   r   r   Ú<module>r°     sœ  ðñó Ý Û 	Û 	Û Û Û 
Ý ß 'å 2÷uõ uå 5ð 
×	Ò	Ð2Ó	3€à!OÐ ñ 'ò (qó rÐ ð
 —J’JÐMÓNÐ ò MÐ ð ÐXØ�-ØÐ0ØÐBØ	ÐðÐ ð L€ð	°U÷ 	õG÷&ðR¸Uð Èt÷ õ4Qõ÷ð"45¸ð 45Èð 45ÐUY÷ 45ðn0\Ø-/ð0\ØVZ÷0\õfS÷h÷6Uõõ(õ"Gõõ
õ2*õ	b÷÷06õPõf	=÷13ðj%À5ð %Ø,0ð%ØRVð%à&*÷%ñ %r   