Ë
    ãß²jã;  ã            	       ó6  — d Z ddlZddlZddlZddlZddlZddlmZ  ej                  d«      Z	h d£Z
dZd„ d„ cZZd	ed
fgd	edfgdedfdedfgdedfgdœZdZdZdZddddœZdddddœZdededefd „Zdedefd!„Zd"„ Zd#„ Zd+d$„Zd%„ Zd&Z	 	 d,d'ed(ed)edefd*„Zy)-zÆAtomic multi-op batch path for ``skill_manage``. Origin state
(``skill_manage``/``_find_skill``/``_skill_gate_bypass``) is reached lazily
through ``tools.skill_manager_tool`` so that module owns it.é    N)ÚPathztools.skill_manager_tool>   ÚpatchÚcreateÚ
write_fileÚremove_fileé   c                 ó   — |  S ©N© ©Úvs    ú>/home/ubuntu/.hermes/hermes-agent/tools/skill_manager_batch.pyú<lambda>r      s   €  A € ó    c                 ó
   — | d u S r
   r   r   s    r   r   r      s
   € °1¸°9€ r   ÚcontentzVcontent is required for 'create'. Provide the full SKILL.md text (frontmatter + body).zOcontent is required for a full rewrite. Provide the full updated SKILL.md text.Ú	file_pathzJfile_path is required for 'write_file'. Example: 'references/api-guide.md'Úfile_contentz*file_content is required for 'write_file'.z(file_path is required for 'remove_file'.)r   Úeditr   r   uP  old_string is required for 'patch' and must be the EXACT text currently in the file. Read the target file first (read_file on the skill's SKILL.md, or the file named by file_path) and copy the snippet verbatim, then retry 'patch'. Do NOT fall back to action='write_file' â€” that rewrites the entire file and destroys unrelated content.zOnew_string is required for 'patch'. Use an empty string to delete matched text.zfPass EITHER content (full SKILL.md rewrite) OR old_string/new_string (targeted replacement), not both.z!create (and a full-rewrite patch)z"a targeted patch (with old_string)r   )r   Ú
new_stringr   ))r   z	'content'))r   r   zIold_string/new_string (targeted) or 'content' (full rewrite, last resort)))r   z'file_content')r   r   r   r   ÚactionÚargsÚreturnc                 óÒ   — | t         vryt         |    \  }}t        D �cg c]  }||vsŒ|j                  |«      €Œ|‘Œ }}|sydj                  d„ |D «       «      }d|› d|› d�S c c}w )zXSentence naming the text-slot key(s) this op carries that ``action`` never reads, or ''.Ú z and c              3   ó<   K  — | ]  }d |› dt         |   › d�–— Œ y­w)ú'z' (that key is for ú)N)Ú_TEXT_SLOT_OWNER)Ú.0Úks     r   ú	<genexpr>z'_misplaced_text_hint.<locals>.<genexpr>>   s(   è ø€ Ò[ÐPQ˜Q˜q˜cÐ!4Ô5EÀaÑ5HÐ4IÈÔKÑ[ùs   ‚z Note: this op carries u    â€” move that text to ú.)Ú_TEXT_SLOT_FORr   ÚgetÚjoin)r   r   ÚreadsÚdestinationr!   ÚstrayÚcarrieds          r   Ú_misplaced_text_hintr+   6   sz   € à”^Ñ#ØÜ'¨Ñ/Ñ€Eˆ;Ü(ÖW�1¨A°UªN¸t¿x¹xÈ»{Ñ?VŠQÐW€EÐWÙØØ�l‰lÑ[ÐUZÔ[Ó[€GØ$ W IÐ-DÀ[ÀMÐQRÐSÐSùò	 Xs   ž	A$¨A$ºA$c                 óÈ  — t         j                  | d«      D ].  \  }}} ||j                  |«      «      sŒ|t        | |«      z   c S  | dk(  r–|j                  d«      r(|j                  d«      s|j                  d«      �t        S |j                  d«      s$|j                  d«      st        t        | |«      z   S |j                  d«      s|j                  d«      €t
        S y)a  Argument-shape error text for one op, or None. Only shape misses carry the misplaced-text
    hint: a patch whose real problem is an unmatched old_string must not be steered to a full
    rewrite. Pure function so the batch can reject a misfiled op BEFORE any sibling is applied.r   r   r   Ú
old_stringr   N)Ú_REQUIRED_ARGSr%   r+   Ú_PATCH_EITHER_ORÚ_PATCH_NEEDS_OLD_STRINGÚ_PATCH_NEEDS_NEW_STRING)r   r   ÚargÚmissingÚmessages        r   Ú_op_shape_errorr5   B   sÐ   € ô "0×!3Ñ!3°F¸BÓ!?ò @ÑˆˆW�gÙ�4—8‘8˜C“=Õ!ØÔ1°&¸$Ó?Ñ?Ò?ð@ð �Òð �8‰8�IÔ D§H¡H¨\Ô$:¸d¿h¹hÀ|Ó>TÐ>`Ü#Ð#Ø�x‰x˜Ô%¨d¯h©h°yÔ.AÜ*Ô-AÀ&È$Ó-OÑOÐOØ�x‰x˜	Ô" t§x¡x°Ó'=Ð'EÜ*Ð*Ør   c                 óä  ‡— ddl m} ˆfd„}g }t        | «      D �]  \  }}t        |t        «      r|j                  d«      s ||d«      c S |d   }|t        vr. ||d|› ddj                  t        t        «      «      › d	�«      c S |j                  d
«      xs |}	|	s ||d«      c S t        ||«      x}
� ||d|› d|	› d|
› �«      c S |j                  |	«       |dk(  r|	|dd v r ||d|	› d�«      c S  |||	«      x}€Œêdt        j                  |d¬«      fc S  t        «       }t        | «      D ]¶  \  }}|d   ||   }	}|dk(  xr t        |j                  d«      «      }|j                  d«      xs dj                  «       }|dk(  s|s|sdn#t!        j"                  |j%                  d«      «      }|	|f}|dv s|r||v r ||d|› d|› d|	› d�«      c S |j'                  |«       Œ¸ |dfS ) zOShape checks with no side effects. Returns (names, None) or (None, error_json).r   )Ú_background_review_preflightc                 ó(   •— d  ‰d| › d|› �d¬«      fS )Núoperations[ú]F©Úsuccessr   )ÚiÚmsgÚ
tool_errors     €r   Úfailz!_validate_batch_ops.<locals>.failX   s"   ø€ Ø‘Z +¨a¨S°°#°Ð 7ÀÔGÐGÐGr   r   z needs an 'action'.z: unknown action 'z'. Batchable: ú, z; delete must be sole.Únamez' needs a 'name' (the skill it targets).Nz (ú on 'z'): r   éÿÿÿÿz: create for 'z&' must precede that skill's other ops.F©Úensure_asciir   r   r   r   zSKILL.mdú/)r   r   r   z: z' of skill 'uò   ' â€” an earlier op in this batch already touched that file, and this op would silently discard its work. One destructive op (write_file/remove_file/full rewrite) per file per batch; put it first, or fold the change in. Patch chains are fine.)Útools.skill_manager_guardsr7   Ú	enumerateÚ
isinstanceÚdictr%   Ú_BATCH_OP_ACTIONSr&   Úsortedr5   ÚappendÚjsonÚdumpsÚsetÚboolÚstripÚ	posixpathÚnormpathÚlstripÚadd)Ú
operationsÚdefault_namer?   r7   r@   Únamesr=   ÚopÚactÚnmÚ	shape_errÚ	preflightÚtouched_filesÚfull_rewriteÚfpÚtargetÚkeys     `              r   Ú_validate_batch_opsre   U   sI  ø€ åGôHà€EÜ˜:Ó&ó C‰ˆˆ2Ü˜"œdÔ#¨2¯6©6°(Ô+;Ù˜Ð0Ó1Ò1Ø�‰lˆØÔ'Ñ'Ù˜Ð/°¨u°NØ"Ÿi™i¬Ô/@Ó(AÓBÐCÐCYð[ó \ò \à�V‰V�F‹^Ò+˜|ˆÙÙ˜ÐDÓEÒEô )¨¨bÓ1Ð1ˆIÐ>Ù˜˜R ˜u E¨"¨¨T°)°Ð=Ó>Ò>Ø�‰�RÔØ�(Š?˜r U¨3¨B ZÑ/Ù˜˜^¨B¨4Ð/UÐVÓWÒWÙ5°c¸2Ó>Ð>ˆIÑKØœŸ™ I¸EÔBÐBÒBð%Cô, “E€MÜ˜:Ó&ò ‰ˆˆ2Ø�X‘,  a¡ˆRˆà˜g‘~ÒA¬$¨r¯v©v°iÓ/@Ó*AˆØ�f‰f�[Ó!Ò' R×.Ñ.Ó0ˆØ!$¨¢±LÉ‘*Ü ×)Ñ)¨"¯)©)°C«.Ó9ð 	à�6ˆlˆØÐ:Ñ:¹lÐPSÐWdÑPdÙ˜˜R ˜u E¨&¨°¸b¸Tð BUð Vó Wò Wð 	×Ñ˜#Õðð �$ˆ;Ðr   c                 ó,  — i }t         j                  | «      D ]U  } ||«      }|rt        |d   «      nd}|�|j                  «       r||z  nd}|�	 t	        j
                  ||«       ||f||<   ŒW |dfS # t        $ r}dd|› d|› �fcY d}~c S d}~ww xY w)zPCopy every touched skill aside. Returns (snapshots, None) or (None, error_text).ÚpathNzCould not snapshot 'z' for atomic batch: )rK   Úfromkeysr   Úis_dirÚshutilÚcopytreeÚ	Exception)	rZ   Ú	snap_rootÚ
find_skillÚ	snapshotsr]   ÚpreÚpre_dirÚsnapÚexcs	            r   Ú_snapshot_skillsrt   ƒ   s¶   € à€IÜ�m‰m˜EÓ"ò 	(ˆÙ˜‹nˆÙ'*”$�s˜6‘{Ô#°ˆØ!(Ð!4¸¿¹Ô9Iˆy˜2Š~ÈtˆØÐðRÜ—‘ ¨Ô.ð ! $˜ˆ	�"Šð	(ð �dˆ?Ðøô ò RØÐ3°B°4Ð7KÈCÈ5ÐQÐQ×QûðRús   ÁA4Á4	BÁ=	BÂBÂBc                 óê  — |d uxr |j                  «       }|€|rt        j                  |«       y |st        j                  || «       y |j	                  |j
                  dz   «      }t        j                  |d¬«       |j                  |«       	 t        j                  || «       t        j                  |d¬«       y # t        $ r* t        j                  | d¬«       |j                  | «       ‚ w xY w)Nz.rollback-brokenT©Úignore_errors)ri   rj   Úrmtreerk   Ú	with_namerB   Úrenamerl   )rq   rr   Úpost_dirÚpost_existsÚasides        r   Ú_restore_snapshotr~   “   sÊ   € Ø $Ð&Ò<¨8¯?©?Ó+<€KØ€|ÙÜ�M‰M˜(Ô#ØÙÜ�‰˜˜gÔ&Øð ×Ñ˜xŸ}™}Ð/AÑAÓB€EÜ
‡M�M�% tÕ,Ø‡O�O�EÔðÜ�‰˜˜gÔ&ô ‡M�M�% tÖ,øô ò ä�‰�g¨TÕ2Ø�‰�WÔØð	ús   ÂB? Â?3C2c           	      ó:  — g }| j                  «       D ].  \  }\  }}	  ||«      }t        |||rt        |d   «      nd«       Œ0 |rd	j                  |«      nd
t        |«      fS # t        $ r-}|j	                  d|› d|› d�|�d|› d�ndz   «       Y d}~Œ‚d}~ww xY w)z/Restore every snapshot. Returns (note, failed).rg   NzROLLBACK FAILED for 'z' (r   z; snapshot preserved at 'r   r   z; zall touched skills rolled back)Úitemsr~   r   rl   rN   r&   rR   )ro   rn   Únotesr]   rq   rr   Úpostrs   s           r   Ú	_rollbackrƒ   «   sÄ   € à€EØ(Ÿ™Ó0ò ^Ñˆ‰OˆW�dð	^Ù˜b“>ˆDÜ˜g tÁ4¬T°$°v±,Ô-?ÈTÕRð^ñ !&ˆD�I‰I�eÔÐ+KÌdÐSXËkÐYÐYøô ò 	^Ø�L‰LÐ0°°°C¸°u¸AÐ>ØCGÐCSÐ7¸°v¸QÑ?ÐY[ñ]÷ ^ñ ^ûð	^ús   �%A$Á$	BÁ-#BÂB)Úlint_warningsÚ	lint_hintÚorg_sharingrY   Útask_idÚ
session_idc                 ór  ‡ ‡— ddl m} ddlm} t	        ‰ t
        «      r‰ s
 |dd¬«      S t        ‰ «      t        kD  r |dt        › d�d¬«      S t        d	„ ‰ D «       «      rdt        ‰ «      d
k7  r
 |dd¬«      S ‰ d   j                  d«      xs |}|s
 |dd¬«      S |j                  d|||‰ d   j                  d«      ¬«      S t        ‰ ||«      \  Š}|�|S |j                  j                  «       sˆˆ fd„}|j                  |«      }	|	�|	S |j                  ‰«      5  t        t!        j"                  d¬«      «      }
t%        ‰|
|j&                  «      \  }}|�*t)        j*                  |
d¬«        ||d¬«      cddd«       S g }d}|j                  j-                  d«      }	 t/        ‰ «      D �]–  \  }}|j1                  i |¥‰|   ddœ¥||¬«      }	 t3        j4                  |«      }|j                  d«      såt9        ||j&                  «      \  }}dd|› d|d   › d‰|   › d |j                  d!d"«      › d#|› d$�||d%œ}|j;                  «       D ]  \  }}|dvsŒ|€Œ|j=                  ||«       Œ! t3        j>                  |d¬&«      c |j                  jA                  |«       |rtB        jE                  d'|
«       nt)        j*                  |
d¬«       cddd«       S ‰|   |d   |j                  d(«      dd)œ}|jG                  tH        D �ci c]  }|j                  |«      €Œ|||   “Œ c}«       |jK                  |«       �Œ™ 	 |j                  jA                  |«       |rtB        jE                  d'|
«       nt)        j*                  |
d¬«       	 ddd«       t3        j>                  dt        «      |d*œd¬&«      S # t6        $ r	 dddœ}Y �Œéw xY wc c}w # |j                  jA                  |«       |rtB        jE                  d'|
«       w t)        j*                  |
d¬«       w xY w# 1 sw Y   Œ—xY w)+av  Apply operations atomically: every touched skill is snapshotted first and any
    failure rolls ALL of them back (batch-created skills are removed). ``delete`` is
    only legal as the SOLE op (its recoverable-archive path doesn't compose with
    rollback) and routes to the single-op handler. ``default_name`` is the legacy
    top-level ``name`` fallback (staged replay).r   )Úskill_manager_tool)r?   z%operations must be a non-empty array.Fr;   zoperations is capped at z ops per call.c              3   óh   K  — | ]*  }t        |t        «      xr |j                  d «      dk(  –— Œ, y­w)r   ÚdeleteN)rJ   rK   r%   ©r    r[   s     r   r"   z&_skill_manage_batch.<locals>.<genexpr>È   s-   è ø€ Ò
VÀRŒ:�bœ$ÓÒ@ B§F¡F¨8Ó$4¸Ñ$@Ó@Ñ
Vùs   ‚02é   uW   delete must be the SOLE op in its call â€” it doesn't compose with other ops' rollback.rB   z&operations[0] (delete) needs a 'name'.rŒ   Úabsorbed_into)r   rB   r‡   rˆ   r�   Nc                 ó¬   •— dj                  d„ ‰D «       «      }dt        ‰«      › d|› ddj                  t        t        ‰«      «      «      › �}d‰dœ|fS )NrA   c              3   ó&   K  — | ]	  }|d    –— Œ y­w)r   Nr   r�   s     r   r"   z8_skill_manage_batch.<locals>._staging.<locals>.<genexpr>×   s   è ø€ Ò?¨b˜R �\Ñ?ùs   ‚zbatch(z ops: z) on Úbatch)r   rX   )r&   ÚlenrM   rQ   )ÚwaÚactsÚgistrZ   rX   s      €€r   Ú_stagingz%_skill_manage_batch.<locals>._stagingÖ   sX   ø€ Ø—9‘9Ñ?°JÔ?Ó?ˆDØœC 
›OÐ,¨F°4°&¸¸d¿i¹iÌÌsÐSXËzÓHZÓ>[Ð=\Ð]ˆDØ%°ZÑ@À$ÐFÐFr   Úskill_batch_)ÚprefixTrv   )rB   rX   )r‡   rˆ   zunparseable op result)r<   Úerrorr<   r9   z] (r   rC   z') failed: rš   zunknown erroru    â€” batch aborted, r#   )r<   rš   Úfailed_indexÚcompleted_before_failurerE   z8skill_manage batch rollback failed, snapshots kept at %sr   )rB   r   r   r<   )r<   Úoperations_appliedÚresults)&ÚtoolsrŠ   Útools.registryr?   rJ   Úlistr“   Ú_BATCH_MAX_OPSÚanyr%   Úskill_managere   Ú_skill_gate_bypassÚ_run_write_gateÚ_skill_mutation_locksr   ÚtempfileÚmkdtemprt   Ú_find_skillrj   rx   rQ   rI   Ú_skill_manage_fromrO   Úloadsrl   rƒ   r€   Ú
setdefaultrP   ÚresetÚloggerÚwarningÚupdateÚ_ADVISORY_KEYSrN   )rX   rY   r‡   rˆ   Ú_smtr?   r]   Úerrr—   Ústagedrm   ro   Úsnap_errrž   Úrollback_failedÚtokenr=   r[   ÚrawÚparsedÚnoter@   r!   r   ÚentryrZ   s   `                        @r   Ú_skill_manage_batchr½   »   sE  ù€ õ 1Ý)Ü�j¤$Ô'©zÙÐAÈ5ÔQÐQÜ
ˆ:ƒœÒ'ÙÐ4´^Ð4DÀNÐSÐ]bÔcÐcÜ
Ñ
VÈ:Ô
VÔVÜˆz‹?˜aÒÙð BØKPôRð Rà˜‰]×Ñ˜vÓ&Ò6¨,ˆÙÙÐFÐPUÔVÐVØ× Ñ ¨°rÀ7ÐWaØ/9¸!©}×/@Ñ/@ÀÓ/Qð !ó Sð 	Sä$ Z°¸zÓJ�J€Eˆ3Ø
€Øˆ
Ø×"Ñ"×&Ñ&Ô(õ	Gð ×%Ñ% hÓ/ˆØÐØˆMð 
×	#Ñ	# EÓ	*ñ +=Üœ×)Ñ)°Ô@ÓAˆ	Ü.¨u°iÀ×AQÑAQÓRÑˆ	�8ØÐÜ�M‰M˜)°4Õ8Ù˜h°Ô6÷+=ñ +=ð ˆØˆØ×'Ñ'×+Ñ+¨DÓ1ˆð!	=Ü" :Ó.ó &‘��2Ø×-Ñ-Ð.Z°Ð.Z¸UÀ1¹XÐUYÒ.ZØ6=È*ð .ó V�ðRÜ!ŸZ™Z¨›_�Fð —z‘z )Ô,Ü,5°iÀ×AQÑAQÓ,RÑ)�D˜/à#(Ø$/°¨s°#°b¸±l°^À5ÈÈqÉÈ
ÐR]Ø%+§Z¡Z°¸Ó%IÐ$JÐJ^Ð_cÐ^dÐdeð#gà()Àqñ	J�Dð !'§¡£ò 2™˜˜1ØÐ$8Ò8¸Q¹]Ø ŸO™O¨A¨qÕ1ð2ô  Ÿ:™: d¸Ô?Ñ?ð ×#Ñ#×)Ñ)¨%Ô0Ùä—‘ÐYÐ[dÕeä—‘˜i°tÕ<÷W+=ñ +=ð> "' q¡°R¸±\Ø&(§f¡f¨[Ó&9ÀdñL�ð —‘´NÖ`¨qÀfÇjÁjÐQRÃmÑF_˜a ¨¡™lÒ`ÔaØ—‘˜uÖ%ñ3&ð6 ×#Ñ#×)Ñ)¨%Ô0Ùä—‘ÐYÐ[dÕeä—‘˜i°tÖ<÷W+=ô` �:‰:Ø´°G³ÈÑQØôð øôA !ò RØ).Ð9PÑQ“FðRüò& aøð ×#Ñ#×)Ñ)¨%Ô0Ùä—‘ÐYÐ[dÕeä—‘˜i°tÖ<ú÷W+=ð +=ús}   ÄAP-ÆP-Æ%0OÇOÇ+A1OÉOÉ ,OÊAP-Ë!/OÌOÌ'OÌ/OÍAP-ÏOÏOÏOÏOÏAP*Ð*P-Ð-P6)r   N)NNN)Ú__doc__rO   ÚloggingrT   rj   r¨   Úpathlibr   Ú	getLoggerr¯   rL   r¢   Ú_MISSINGÚ_IS_NONEr.   r0   r1   r/   r   r$   ÚstrrK   r+   r5   re   rt   r~   rƒ   r²   r½   r   r   r   ú<module>rÅ      so  ðñ@ó Û Û Û Û Ý à	ˆ×	Ñ	Ð5Ó	6€âDÐ Ø€ñ &Ñ)<Ð €ˆ(à˜8Øhðjð kà˜Ø_ðað bð 
�hÐ lÐmØ	˜Ð#OÐPðRð ! (Ð,VÐWÐXñZ€ð\ð ð
 lÐ ð8Ð ð  CØ"FØ$0ñ2Ð ð
 *Ø'ØuØ7ñ	9€ð	T ð 	T¨Dð 	T°Só 	Tð˜Cð  tó ò&+ò\ó -ò0
Zð ?€ð NRØ*.ñW°#ð WÀsð WØ$'ðWØ36ôWr   