+
    lHàjÇ ã                   ód	  € R t ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHtH	t	H
t
 ^ RIHtHtHt ^ RIHt ^ RIHtHt Rt0 RÉmtRRÊR	RËR
RÌRRÍ/tR^ R^R^/t]	 ! R R4      4       t]	 ! R R4      4       tRtRtRtRtR R ltR R ltR R ltRt Rt!Rt"R t#R!t$R"t%R#t&R$t'R%t(R&](,           R',           t)R(]),           R),           t*. RÎNRÏNRÐNRÑNRÒNRÓNRÔNRÕNRÖNR×NRØNRÙNRÚNR-]),           R.R*R+R/3NR0]*,           R1,           R2,           ]*,           R3,           R4R*R+R53NRÛNRÜNRÝNRÞNRßNRàNRáNRâNRãNRäNRåNRæNRçNRèNRéNRêNRëNRìNRíNRîNRïNRðNRñNRòNRóNRôNRõNRöNR÷NRøNRùNRúNRûNRüNRýNRþNRÿNER NERNERNERNERNERNERNR9]& R:2R;R*R7R<3NERNERNER	NER
NERNERNERNERNR>]& R?2R@R*R=RA3NERNERNERNERNERNERNERNERNERNERNERNERNERNERNERNERNERNER NER!NER"NER#NER$NER%NRD]' ]& 2RER*RFRG3NRH]' ]& 2RIR*RFRJ3NRD]' RK2RLR*RFRM3NER&NER'NER(NER)NER*NER+NER,NER-NER.NER/NER0NER1NER2N]! ]4      ROR*R6RP3N]! ]4      RQR*R6RR3N]! ]4      RSR,R6RT3NER3N]! ]4      RUR,R6RV3N]! ]4      RWR*R6RX3NER4N]! ]4      RYR,R6RZ3N]! ]4      R[R*R6R\3NER5NER6NER7NER8NER9NER:NER;NER<NER=NER>NER?NER@NERANERBNERCNR]]  ]! R^]  ]" R_]# R`]$ Ra]% Rb2RcR,R+Rd3NERDNt+]+ U Uu. uF$  vr]PY                  V ]PZ                  4      .VO5NK&  	  upp t.]/! 0 EREm4      t0/ ReRfbRgRfbRhRfbRiRfbRjRfbRkRfbRlRfbRmRfbRnRfbRoRfbRpRfbRqERFbRrERFbRsRtbRuRtbRvERGbt1]PX                  ! Rw]PZ                  4      t2]PX                  ! Rx]PZ                  4      t3]PX                  ! Ry4      t4Rz R{ lt5R| R} lt6^2R~Rut7t8t90 ERHmt:0 ERImt;0 ERJmt</ R€R�bR‚RƒbR„R…bR†R‡bRˆR‰bRŠR‹bRŒR�bRŽR�bR�R‘bR’R“bR”R•bR–R—bR˜R™bRšR›bRœR�bRžRŸbR R¡bt=]>! ]=4      t?RCRB0t@R¢ R£ ltAR¤ R¥ ltBR¦ R§ ltC]PX                  ! R¨4      tD]PX                  ! R©4      tERª R« ltFERKR­ R® lltG]/! RNR804      tHR¯ R° ltIERLR± R² lltJR³ R´ ltKRµ R¶ ltLERLR·R¬R¸R/R¹ Rº llltMERMR» R¼ lltNR½ R¾ ltOERNR¿ RÀ lltPEROtQRÁ RÂ ltRERPtSRÃ RÄ ltTRÅ RÆ ltURÇ RÈ ltVR# u upp i (Q  ug  Skills Guard â€” regex static scan of externally-sourced skills plus a trust-aware install policy.

Trust: builtin (never scanned), trusted (openai/anthropics/... repos: caution allowed), community (any
findings block unless --force). ``scan_skill`` -> ``should_allow_install`` -> ``format_scan_report``.
Known gap: language write APIs (open(..., 'w'), Path.write_text, shutil.copy*, fs.writeFileSync) aimed at
agent-config files surface only the low *_ref finding â€” static regexes cannot tie the call to a dynamic
destination; future coverage belongs as a fourth "mechanical" tier next to agent_config_mod_shell.N)Úsuppress)ÚasdictÚ	dataclassÚfield)ÚdatetimeÚtimezoneÚUTC©ÚPath)ÚListÚTuplezskills-guard-v10ÚbuiltinÚtrustedÚ	communityúagent-createdÚsafeÚcautionÚ	dangerousc                   ó,   a € ] tR t^&t o V 3R ltRtV tR# )ÚFindingc                ón   <€ V ^8„  d   Qh/ S[ ;R&   S[ ;R&   S[ ;R&   S[ ;R&   S[;R&   S[ ;R&   S[ ;R&   # )é   Ú
pattern_idÚseverityÚcategoryÚfileÚlineÚmatchÚdescription)ÚstrÚint)ÚformatÚ__classdict__s   "€Ú7/home/ubuntu/.hermes/hermes-agent/tools/skills_guard.pyÚ__annotate__ÚFinding.__annotate__&   sX   ø‡ ‚ á�Oñ ñ �Mñ ñ �Mñ	 ñ
 �Iñ ñ �Iñ ñ �Jñ ñ Ñò ó    © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__©r"   s   @r#   r   r   &   s   ø‡ ‡ „ r&   r   c                   óX   a € ] tR t^1t o ]! ]R7      tRtRt]! ]	R7      t
V 3R ltRtV tR# )Ú
ScanResult)Údefault_factoryÚ c                óŠ   <€ V ^8„  d   Qh/ S[ ;R&   S[ ;R&   S[ ;R&   S[ ;R&   S[S[,          ;R&   S[ ;R&   S[ ;R&   S[;R&   # )	r   Ú
skill_nameÚsourceÚtrust_levelÚverdictÚfindingsÚ
scanned_atÚsummaryÚscan_provenance)r   Úlistr   Údict)r!   r"   s   "€r#   r$   ÚScanResult.__annotate__1   sl   ø‡ ‚ á�Oñ ñ �Kñ ñ Ññ	 ñ
 �Lñ ñ ‘7�mÑ9ñ ñ Ññ ñ Ññ ñ Ñ7ò r&   r'   N)r(   r)   r*   r+   r   r=   r9   r:   r;   r>   r<   r,   r-   r.   r/   s   @r#   r1   r1   1   s,   ø‡ € ñ $°DÔ9€HØ€JØ€GÙ!°$Ô7€O÷ ƒ r&   r1   a0  (?:\bwrit(?:e|es|ing)\b|\bwritten\b|\bedit(?:s|ed|ing)?\b|\bmodif(?:y|ies|ied|ying|ication)s?\b|\bupdat(?:e|es|ed|ing)\b|\bappend(?:s|ed|ing)?\b|\bprepend(?:s|ed|ing)?\b|\binject(?:s|ed|ing)?\b|\boverwrit(?:e|es|ing)\b|\boverwritten\b|\breplac(?:e|es|ed|ing)\b|\balter(?:s|ed|ing)?\b|\badd(?:s|ed|ing)\b)z4(?:AGENTS\.md|CLAUDE\.md|\.cursorrules|\.clinerules)z"\.hermes/(?:config\.yaml|SOUL\.md)z(\.(?:claude/settings|codex/config)[\w.]*c                ó0   € V ^8„  d   QhR\         R\         /# ©r   Úfile_altÚreturn©r   )r!   s   "r#   r$   r$   M   s   € ÷ 	Mñ 	Mœcð 	M¤cñ 	Mr&   c           	     ó    € RV  RV  RV  RV  R2	# )a“  Mechanical shell write into *file_alt*: ``>``/``>>``, ``sed -i``, ``tee`` (target as immediate argument, so
``| tee output | AGENTS.md |`` cells miss), ``cp``/``mv`` with the file as destination (source arg required, so
``cp AGENTS.md backup/`` misses; ``AGENTS.md.bak`` is not the file). A single ``>`` needs a preceding word/quote/
paren char so blockquotes (``> text``) and arrows (``-> file``) miss.z"(?:>>|[\w"\'`)\]]\s*>)\s*[~\w./-]*zD(?!\.?\w)|\bsed\b[^\n]*\s(?:-[A-Za-z]*i[A-Za-z]*|--in-place)\b[^\n]*z((?!\.?\w)|\btee\s+(?:-a\s+)?[~\w./"\'-]*z3(?!\.?\w)|\b(?:cp|mv)\s+[^\s|;&]+\s+[^\n|;&]{0,40}?z	(?!\.?\w)r'   ©rB   s   &r#   Ú_shell_write_rerG   M   s9   € ð .¨h¨Zð 8GØGOÀjð Q+Ø+3¨*ð 58Ø8@°zÀð	LðMr&   c                ó0   € V ^8„  d   QhR\         R\         /# rA   rD   )r!   s   "r#   r$   r$   Y   s   € ÷ 9ñ 9œsð 9¤sñ 9r&   c           	     ó0   € R\          RV  R\          RV  R2	# )uL  Prose instructing modification of *file_alt*: an imperative-position verb (line start / bullet), or a mid-line
verb with a directive marker ("you must", "please", "make sure to"). Descriptive prose ("skills that edit
AGENTS.md") misses; the verbâ†’file gap forbids commas so enumerations ("Write skills, AGENTS.md, CLAUDE.md") miss.z^\s*(?:[-*+]\s+|\d+[.)]\s+)?z[^\n,]{0,80}?zl\b|(?:\byou\s+(?:must|should|need\s+to)\s+|\bplease\s+|\bmake\s+sure\s+(?:to\s+|you\s+)|\bbe\s+sure\s+to\s+)z\b)ÚMODIFY_VERB_RErF   s   &r#   Ú_prose_modify_rerK   Y   s3   € ð
 (¬Ð'7°ÀxÀjð QBô Ð˜?¨8¨*°Bð	8ð9r&   c                ó0   € V ^8„  d   QhR\         R\         /# rA   rD   )r!   s   "r#   r$   r$   d   s   € ÷ mñ m¤3ð m¬3ñ mr&   c                ó   € V  R2# )uÁ   "<file> should contain/include ..." prose. Authoring guides and attacks share this shape and are not
separable statically, so the tier is scored high (caution â†’ confirmation), never critical.zQ\b[^\n]{0,40}?\b(?:should|must|needs?\s+to)\s+(?:contain|say|include|have|list)\br'   rF   s   &r#   Ú_content_contract_rerN   d   s   € ð ˆjÐkÐlÐlr&   zw(?!(?:\w+\s+){0,4}?(?:never|not|no|doesn\'?t|didn\'?t|won\'?t|isn\'?t|aren\'?t|can\'?t|cannot|mustn\'?t|shouldn\'?t)\b)z(?:\w+\s+){0,3}?zš(?!(?:(?:the|your|each|every|all|to|a)\s+)?(?:sub-?agents?|sub-?tasks?)\b|(?:(?:the|your|each|every|all|to|a)\s+)(?:workers?|delegates?|children|child)\b)zƒ(?:your|their|our|its|the\s+(?:full|entire|whole|complete|current)|full|entire|whole|complete|current|conversation|session|chat)\s+z(?:\s+(?:to|at|with)\b)z&(?:[a-z]+s\s+)(?:the|a|an)\s+context\bz(?:bash|sh|zsh|ksh|dash)\bz(?:sudo\s+(?:-\S+\s+)*)?zs(?:\.ssh[/\\]id_(?:rsa|ed25519|ecdsa|dsa)(?!\.pub)|\.env\b|credentials\b|\.netrc\b|\.pgpass\b|\.npmrc\b|\.pypirc\b)z["\'][^"\'\n]*z[^"\'\n]*["\']z!(?:os\.path\.expanduser\s*\(\s*)?z\s*\)?ÚcriticalÚexfiltrationÚhighz,\b(?:readFile(?:Sync)?|readTextFile)\s*\(\s*Újs_read_secrets_filez(JavaScript reads a known credential filez\bopen\s*\(\s*zV(?!\s*\)?\s*,\s*["\'][^"\']*[wax][^"\']*["\'])(?![^\n]*\bmode\s*=\s*["\'][^"\']*[wax])z|\bPath\s*\(\s*z7\s*\)\.(?:read_text|read_bytes|readlines|readline)\s*\(Úpy_read_secrets_filez$Python reads a known credential fileÚpersistenceÚnetworkÚbind_all_interfacesz/bin/z\s+-i\s+.*>/dev/tcp/Úbash_reverse_shellz+bash interactive reverse shell via /dev/tcpÚobfuscationzecho\s+[^\n]*\|\s*(?:z|python|perl|ruby|node)Úecho_pipe_execz'echo piped to interpreter for executionÚpath_traversal_deepÚpath_traversalzcurl\s+[^|\s][^\n]*\|\s*Úcurl_pipe_shellÚsupply_chainz*curl piped to shell (download-and-execute)zwget\s+[^\n]*-O\s*-\s*\|\s*Úwget_pipe_shellz*wget piped to shell (download-and-execute)ÚpythonÚcurl_pipe_pythonz curl piped to Python interpreterÚ
sudo_usageÚagent_config_modzYinstructs modification of agent config files (could persist instructions across sessions)Úagent_config_mod_shellz\shell write (redirect/sed -i/tee/cp/mv) targeting agent config files (persistence mechanism)Úagent_config_contractu[   dictates agent config file contents (verify intent â€” authoring guides use this shape too)Úhermes_config_modzImodification language aimed at Hermes configuration files (verify intent)Úhermes_config_mod_shellzLshell write (redirect/sed -i/tee/cp/mv) targeting Hermes configuration filesÚother_agent_config_modz*modifies other agents' configuration filesÚother_agent_config_mod_shellzSshell write (redirect/sed -i/tee/cp/mv) targeting other agents' configuration filesz(\b(?:include|output|print|send|share)\s+zf(?:conversation|chat\s+history|previous\s+messages)\b|\b(?:print|send|share|output|upload|transmit)\s+z(?:(?:\w+\s+){0,2}?z3(?:\w+\s+){0,2}?context\b|(?:\w+\s+){0,3}?context\bÚ|Ú)Úcontext_exfilz4instructs agent to output/share conversation historyú.pyÚ#ú.shú.bashú.rbú.plú.rú.jlú.yamlú.ymlú.tomlú.confú.cfgú.iniú.jsú//ú.tsú.phpz½^\s*(?:(?:const|let|var|export)\s+)?[\w.\-]*(?:deny|black|block|skip|exclu|ignor|forbid|refus|reject|never|unsafe|sensitive|secret_?file|redact)[\w.\-]*\s*(?::[^=]*?)?(?:=|:\s*(?:$|[\[({]))a  \b(?:cat|less|more|head|tail|cp|mv|rm|scp|rsync|curl|wget|tee|chmod|chown|ssh|sudo|install|source|eval|exec|system|popen|run|check_output|copyfile|copy2|sendfile)\b|\.(?:read|write|open|unlink|copy|append)\w*\s*\(|\bopen\s*\(|readFileSync|writeFileSync|appendFileSync|>>z'[^'\n]*'|"[^"\n]*\"c                ó0   € V ^8„  d   QhR\         R\         /# ©r   ÚlinesrC   )r=   )r!   s   "r#   r$   r$   0  s   € ÷ ñ œTð ¤dñ r&   c           	     óp  a€ . ^ ^ R3w  rr4\        V 4       Fœ  w  rVV^ 8:  d   V'       g   TpVP                  V4       \        P                  RV4      o\	        ^ V\        V3R lR 4       4      ,           \        V3R lR 4       4      ,
          4      pVP                  4       P                  R4      pKž  	  V# )aB  0-indexed line that opened each line's statement (an unclosed bracket or trailing backslash continues it),
so a match on a continuation line of a multi-line regex can be traced to the assignment target above it.
Quoted spans are blanked before counting brackets; a miscount costs a missed demotion, never a missed finding.Fr3   c              3   óF   <"  € T F  pSP                  V4      x € K  	  R # 5i©N©Úcount©Ú.0ÚcÚbares   & €r#   Ú	<genexpr>Ú$_statement_owners.<locals>.<genexpr>:  s   øé € Ð"@¹%°Q 4§:¡:¨a§= =»%ùó   ƒ!z([{c              3   óF   <"  € T F  pSP                  V4      x € K  	  R # 5irƒ   r„   r†   s   & €r#   rŠ   r‹   :  s   øé € ÐFdÑ^cÐYZÀtÇzÁzÐRSÇ}À}Ó^cùrŒ   z)]}Ú\)Ú	enumerateÚappendÚ_QUOTED_SPAN_REÚsubÚmaxÚsumÚrstripÚendswith)r€   ÚownersÚdepthÚownerÚ	continuedÚir   r‰   s   &      @r#   Ú_statement_ownersrœ   0  sž   ø€ ð ')¨!¨Q° oÑ#€F�5Ü˜UÖ#‰ˆØ�AŒ:ŸiØˆEØ�‰�eÔÜ×"Ñ" 2 tÓ,ˆÜ�A�uœsÔ"@¹%Ó"@Ó@Õ@Ä3ÔFdÑ^cÓFdÓCdÕdÓeˆØ—K‘K“M×*Ñ*¨4Ó0Š	ñ $ð €Mr&   c                óŽ   € V ^8„  d   QhR\         R\         R\         R\         R\         R\         R\        \         \         3,          /# )r   Úpidr   r   r   Ú
owner_lineÚsuffixrC   )r   Útuple)r!   s   "r#   r$   r$   ?  sI   € ÷ 	!ñ 	!¤cð 	!´Sð 	!Äsð 	!ÔRUð 	!Ôcfð 	!Ü),ð	!Ü16´s¼C°xµñ	!r&   c                ó  € V \         9  d   W3# VP                  4       P                  \        P	                  VR4      4      '       d   RV R23# \
        P                  V4      '       d#   \        P                  V4      '       g   RV R23# W3# )zc``(severity, description)`` for a path-token match, lowered when the line cannot act where it sits.Úlowz (in a comment; informational)rQ   z3 (in a denylist literal; confirm before installing)r'   )	Ú_PATH_REFERENCE_PATTERN_IDSÚlstripÚ
startswithÚ_COMMENT_PREFIXÚgetÚ_DENYLIST_OWNER_REr   Ú_ACTION_ON_LINE_REÚsearch)rž   r   r   r   rŸ   r    s   &&&&&&r#   Ú_demote_inert_path_referencer¬   ?  s‹   € ð Ô-Ô-ØÐ$Ð$Ø‡{�{ƒ}×Ñ¤× 3Ñ 3°F¸BÓ ?×@Ò@Ø˜˜Ð%CÐDÐDÐDÜ×Ñ 
×+Ò+Ô4F×4MÑ4MÈd×4SÒ4SØ˜+˜Ð&YÐZÐZÐZØÐ Ð r&   i   é   u   â€‹zzero-width spaceu   â€Œzzero-width non-joineru   â€�zzero-width joineru   â� zword joineru   â�¢zinvisible timesu   â�£zinvisible separatoru   â�¤zinvisible plusu   ï»¿zBOM/zero-width no-break spaceu   â€ªzLTR embeddingu   â€«zRTL embeddingu   â€¬zpop directionalu   â€­zLTR overrideu   â€®zRTL overrideu   â�¦zLTR isolateu   â�§zRTL isolateu   â�¨zfirst strong isolateu   â�©zpop directional isolatec                ó0   € V ^8„  d   QhR\         R\         /# )r   ÚcharrC   rD   )r!   s   "r#   r$   r$   b  s   € ÷ Añ AœSð A¤Sñ Ar&   c                 óH   € \         P                  V R \        V 4      R 24      # )úU+Ú04X)Ú_INVISIBLE_CHAR_NAMESr¨   Úord)r¯   s   &r#   Ú_unicode_char_namerµ   b  s"   € Ü ×$Ñ$ T¨R´°D³	¸#¨Ð+?Ó@Ð@r&   c                ó0   € V ^8„  d   QhR\         R\        /# r   )r=   Úset)r!   s   "r#   r$   r$   f  s   € ÷ ñ ¤Dð ¬Sñ r&   c                ó6  € \        4       pRp\        V ^R7       Fv  w  r4TR Uu. uF  qTP                  V4      NK  	  pppV\        V4      ^,          ^8H  ,          pV'       g   V'       g   \	        V4      '       g   Ke  VP                  V4       Kx  	  V# u upi )a  1-indexed lines inside or on the boundary of triple-quoted strings (opening, interior, closing, and
one-line docstrings), so ``os.environ`` in prose is not scored. Heuristic: a triple quote inside a string
literal is miscounted, but the common false-positive shapes are covered.F©Ústart)z"""z''')r·   r�   r…   r”   ÚanyÚadd)r€   Ú	doc_linesÚinsider›   r   ÚmarkerÚwas_inÚcountss   &       r#   Ú_compute_docstring_linesrÂ   f  s€   € ô “U€IØ€FÜ˜U¨!×,‰ˆØÁ>Ó!RÁ>¸§*¡*¨VÖ"4Á>�Ð!RˆØ”#�f“+ •/ QÑ&Õ&ˆß—Vœs 6Ÿ{œ{Ø�M‰M˜!Öñ	 -ð
 Ðùò	 "Ss   ¤Bc                ó0   € V ^8„  d   QhR\         R\         /# )r   r   rC   rD   )r!   s   "r#   r$   r$   t  s   € ÷ ñ ¬3ð ´3ñ r&   c                ó   € \        V 4      p^ pV P                  RV4      ;pR	8w  d™   ^pRpV^,           pV\        V 4      8  d{   W,          pV'       d   RpM\VR8X  d   RpMRVR8X  d   V^,          pMAVR8X  d;   V^,          pV^ 8X  d+   RWc,
          ^,
          ,          W^,           V% V^,           pK¥  V^,          pKŠ   RP                  V4      # )
a)  Blank balanced inline-link destinations while preserving line offsets.

A relative Markdown destination describes documentation structure; it does
not cause filesystem access. Nested parentheses and escaped characters are
handled so a later, non-link traversal on the same line remains scannable.
z](FrŽ   TÚ(rj   Ú r3   éÿÿÿÿ)r=   ÚfindÚlenÚjoin)r   ÚmaskedÚsearch_fromrº   r˜   ÚescapedÚcursorr¯   s   &       r#   Ú _mask_markdown_link_destinationsrÏ   t  sË   € ô �$‹Z€FØ€KØ—I‘I˜d KÓ0Ð0ˆ5°RÔ
7ØˆØˆØ˜•ˆØ”s˜4“yÔ Ø•<ˆDßØ‘Ø˜”Ø‘Ø˜”Ø˜•
‘Ø˜”Ø˜•
�Ø˜A”:Ø/2°fµnÀqÕ6HÕ/I�F 1�9 VÐ,Ø"(¨1¥*�KÙØ�a�KŠFàØ�7‰7�6‹?Ðr&   z+^ {0,3}(?P<marker>`{3,}|~{3,})(?P<info>.*)$z-^(?: {0,3}(?:>|(?:[-*+]|\d{1,9}[.)]) {1,4}))+c                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# r   )r=   r   )r!   s   "r#   r$   r$   Ÿ  s"   € ÷ ñ ¬¬c­ð ´t¼Cµyñ r&   c                ób  € . pRpV  EF#  p\         P                  \        P                  RV4      4      pVee   V'       dZ   VR,          ^ ,          V^ ,          8X  d>   \	        VR,          4      V^,          8¼  d    VR,          P                  4       '       g   RpRpMjV'       dF   VR,          ^ ,          R8X  d   RVR,          9   g#   VR,          ^ ,          \	        VR,          4      3pVRJ;'       g    VP                  R4      pTP                  V'       d   TM
\        V4      4       EK&  	  V# )aƒ  Mask link destinations only in Markdown prose. Inside a fenced or indented code block a
``[x](../..)`` is an argument to whatever command surrounds it, not a hyperlink, so those lines
scan verbatim. Fence state is ``(marker_char, opener_length)`` rather than a bool so a
mismatched fence line cannot drop the scanner back into prose mode; an unclosed fence stays
code to EOF (fail-safe).Nr3   r¿   ÚinfoTÚ`)Ú	z    )	Ú_FENCE_LINEr   Ú_CONTAINER_PREFIXr’   rÉ   Ústripr¦   r�   rÏ   )r€   ÚoutÚfencer   r   Úcodes   &     r#   Ú_mask_prose_link_destinationsrÛ   Ÿ  sù   € ð €CØ€EÜˆÜ×!Ñ!Ô"3×"7Ñ"7¸¸DÓ"AÓBˆØÒß˜% �/¨!Õ,°°aµÔ8¼SÀÀxÅÓ=QÐUZÐ[\ÕU]Ô=]Ø! &�M×/Ñ/×1Ò1Ø�Ø‰Dç˜e H�o¨aÕ0°CÔ7¸CÀ5ÈÅ=Ô<PØ˜x�¨Õ+¬S°°xµÓ-AÐB�Ø Ð$×GÐG¨¯©¸Ó(GˆDØ�
‰
Ÿ4‘4Ô%EÀdÓ%K×Lñ ð €Jr&   r3   c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r   Ú	file_pathÚrel_pathrC   )r
   r   r=   r   )r!   s   "r#   r$   r$   ¶  s%   € ÷ ñ œð ¬ð ´d¼7µmñ r&   c                óp  a€ T;'       g    V P                   pV P                  P                  4       \        9  d   V P                   R8w  d   . #  V P	                  RR7      P                  R4      p. p\        T4      pT P                  P                  4       R8X  d   \        T4      MTpT P                  P                  4       \        T4      rv\         FÐ  w  r‰r«p\        T^R7       F¸  w  poT	\        9   d   Y]^,
          ,          MSpYÔ9  g   K*  TP                  T4      '       g   KC  SP                  4       p\!        YšTSY'T^,
          ,          ,          T4      w  ppTP#                  \%        T	TY±T\'        T4      ^x8:  d   TMTR,          R,           T4      4       Kº  	  KÒ  	  \        T^R7       Fe  w  po\)        T3R	 l\*         4       R
4      ;pf   K&  \-        T4      pTP#                  \%        RRRYR\/        T4      R RT R2RT R24      4       Kg  	  T#   \        \        3 d    . u # i ; i)z¹Threat-pattern + invisible-unicode scan of one file; *rel_path* is the display path (default: file
name). Regex findings dedupe per pattern per line; invisible chars yield one per line.úSKILL.mdú	utf-8-sig©ÚencodingÚ
ú.mdr¹   :Néu   Nz...c              3   ó8   <"  € T F  qS9   g   K  Vx € K  	  R # 5irƒ   r'   )r‡   rˆ   r   s   & €r#   rŠ   Úscan_file.<locals>.<genexpr>Î  s   øé € ÐB¡_ ¸T¹	Ÿ!š!£_ùs   ƒ�
NÚinvisible_unicoderQ   Ú	injectionr±   r²   ú (rj   zinvisible unicode character z! (possible text hiding/injection))Únamer    ÚlowerÚSCANNABLE_EXTENSIONSÚ	read_textÚsplitÚUnicodeDecodeErrorÚOSErrorrÂ   rÛ   rœ   Ú_COMPILED_THREAT_PATTERNSr�   Ú_PATH_TRAVERSAL_PATTERN_IDSr«   r×   r¬   r�   r   rÉ   ÚnextÚINVISIBLE_CHARSrµ   r´   )rÝ   rÞ   r€   r9   Údocstring_linesÚtraversal_linesr    r—   Úpatternrž   r   r   r   r›   Ú	scan_lineÚtextÚline_severityÚline_descriptionr¯   rì   r   s   &&                  @r#   Ú	scan_filerþ   ¶  s  ø€ ð ×)Ð)˜9Ÿ>™>€HØ×Ñ×ÑÓÔ';Ô;À	ÇÁÐR\Ô@\Øˆ	ðØ×#Ñ#¨[Ð#Ó9×?Ñ?ÀÓEˆð €HÜ.¨uÓ5€OØ>G×>NÑ>N×>TÑ>TÓ>VÐZ_Ô>_Ô3°EÔ:Ðej€OØ×%Ñ%×+Ñ+Ó-Ô/@ÀÓ/GˆFß9RÑ5ˆ�h¨+Ü  ¨a×0‰GˆAˆtØ25Ô9TÔ2T˜¨A­Ö.ÐZ^ˆIØÖ'¨G¯N©N¸9×,EÔ,EØ—z‘z“|�Ü2NØ ;°°eÀ1ÀqÅ5½MÕ6JÈFó3TÑ/�Ð/à—‘¤¨¨]¸HÐPQÜ03°D³	¸SÔ0@©ÀdÈ4ÅjÐSXÕFXÐZjó!lö mó 1ñ :Sô ˜U¨!×,‰ˆˆ4ÜÔB¥_ÓBÀDÓIÐIˆDÔVÜ% dÓ+ˆDØ�O‰OœGÐ$7¸ÀÈhØ&(¬¨T«°3¨°r¸$¸¸qÐ$AØ&BÀ4À&ÐHiÐ$jólö mñ -ð €Oøô+ ¤Ð(ô ØŠ	ðús   Á!H ÈH5È4H5c                ó0   € V ^8„  d   QhR\         R\         /# )r   ÚfrC   )r   )r!   s   "r#   r$   r$   ß  s   € ÷ ñ ”wð ¤7ñ r&   c                 óè   € V P                   R9   da   V P                  \        9   dL   V P                  P	                  4       P                  R4      '       d   RV P                   R2uV n         V n        V # )rO   rå   Úmediumz) (not executed on install; informational))rO   rQ   )r   r   Ú_DOC_NOTE_IDSr   rí   r–   r   )r   s   &r#   Ú_community_noter  ß  sV   € Ø‡z�zÐ)Ô)Ø�L‰LœMÔ)¨a¯f©f¯l©l«n×.EÑ.EÀe×.LÒ.LØ$,°·±°Ð?hÐ.iÐ!ˆŒ
�A”MØ€Hr&   c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r   Ú
skill_pathr6   rC   )r
   r   r1   )r!   s   "r#   r$   r$   æ  s&   € ÷ Nñ Nœ4ð N¬ð N¼zñ Nr&   c                óê  € V P                   \        V4      r2. pV P                  4       '       dœ   \        V 4      pVP	                  \        WR7      4       V P                  R4       F_  pVP                  4       '       g   K  V! \        VP                  V 4      4      ;p4      '       d   KE  VP	                  \        Wg4      4       Ka  	  M:V P                  4       '       d%   VP	                  \        W P                   4      4       VR8X  d   V Uu. uF  p\        V4      NK  	  pp\        V4      p\        W!W8V\        P                  ! \         4      P#                  4       \%        W!W8V4      4      # u upi )a@  Structural checks + pattern scan of every text file in a skill dir (or a single file). A gitignore-style
`.skillignore` / `.clawhubignore` excludes dev/docs artifacts from BOTH passes; the ignore file itself is
always excluded and `SKILL.md` can never be un-ignored. *source* (e.g. "openai/skills") sets the trust level.)ÚignoreÚ*r   )rì   Ú_resolve_trust_levelÚis_dirÚ_load_skill_ignoreÚextendÚ_check_structureÚrglobÚis_filer   Úrelative_torþ   r  Ú_determine_verdictr1   r   Únowr   Ú	isoformatÚ_build_summary)	r  r6   rì   Útrustr9   r  r   Úrelr8   s	   &&       r#   Ú
scan_skillr  æ  s  € ð —/‘/Ô#7¸Ó#?ˆ%Ø €HØ×Ñ×ÒÜ# JÓ/ˆØ�‰Ô(¨ÔCÔDØ×!Ñ! #Ö&ˆAØ�y‰y�{Œ{¡6´°Q·]±]À:Ó5NÓ1OÐ*O¨#×#PÔ#PØ—‘¤	¨!Ó 1Ö2ò 'ð 
×	Ñ	×	Ò	Ø�‰œ	 *¯o©oÓ>Ô?Ø�ÔÙ08Ó9±¨1”O AÖ&±ˆÐ9Ü  Ó*€GÜ�d E°H¼h¿lºlÌ3Ó>O×>YÑ>YÓ>[Ü$ T°5À8ÓLóNð Nùò :s   ÄE0c                ó0   € V ^8„  d   QhR\         R\        /# ©r   r  rC   ©r
   r   )r!   s   "r#   r$   r$   û  s   € ÷ ñ ¤ð ¬ñ r&   c                óÄ  a € S P                  4       '       g3   \        P                  ! S P                  4       4      P	                  4       # \        P                  ! 4       p\        V 3R lS P                  R4       4       4       FK  w  r#VP                  VP                  R4      R,           4       VP                  VP                  4       4       KM  	  VP	                  4       # )u^  Canonical SHA-256 over (POSIX relative path, file bytes) ORDERED by the rel-path STRING â€” Path sorting is
case-insensitive on Windows and diverged from ``skills_hub.bundle_content_hash`` (every installed skill then
reported ``update_available`` forever). String order keeps both sides byte-symmetric.

Ordering by ``sorted(rglob(...))`` diverged from the bundle side on Windows: Path comparison is
case-insensitive there (normcase), while ``bundle_content_hash`` sorts plain strings â€” the same skill
hashed to different digests and every installed skill reported ``update_available`` forever (#62310).
c              3   ó”   <"  € T F=  qP                  4       '       g   K  VP                  S4      P                  4       V3x € K?  	  R # 5irƒ   )r  r  Úas_posix)r‡   Úpr  s   & €r#   rŠ   Ú"_content_digest.<locals>.<genexpr>  s6   øé € ÐqÑLaÀq×enÑen×epÔB˜!Ÿ-™-¨
Ó3×<Ñ<Ó>ÀÕBÓLaùs
   ƒAŸ)Ar	  úutf-8ó    )	r  ÚhashlibÚsha256Ú
read_bytesÚ	hexdigestÚsortedr  ÚupdateÚencode)r  Úhr  r  s   f   r#   Ú_content_digestr+  û  sŸ   ø€ ð ×Ñ×ÒÜ�~Š~˜j×3Ñ3Ó5Ó6×@Ñ@ÓBÐBÜ�ŠÓ€AÜÔqÈJ×L\ÑL\Ð]`ÔLaÓqÖq‰ˆØ	�‰�—‘˜GÓ$ wÕ.Ô/Ø	�‰�—‘“Ö ñ rð �;‰;‹=Ðr&   c                ó0   € V ^8„  d   QhR\         R\        /# r  r  )r!   s   "r#   r$   r$     s   € ÷ 8ñ 8œTð 8¤cñ 8r&   c                ó,   € R\        V 4      R,           2# )uµ   Short integrity hash (paths mixed in, so swapping two files' contents changes it). MUST stay symmetric
with ``tools.skills_hub_install.bundle_content_hash`` â€” change both at once.úsha256:ºNé   N)r+  )r  s   &r#   Úcontent_hashr1    s   € ð ”_ ZÓ0°Õ5Ð6Ð7Ð7r&   Ú
source_urlÚ	cache_dirc                ó„   € V ^8„  d   QhR\         R\        R\        R\         R,          R\        \        \        3,          /# )r   r  r6   r2  r3  NrC   )r
   r   r¡   r1   r>   )r!   s   "r#   r$   r$     s@   € ÷ ñ ¤$ð ´ð ÔRUð Ü!%¨¥ðÜ8=¼jÌ$Ð>NÕ8Oñr&   c               óÞ  a€ \        V 4      pT;'       g    V P                  R,          p\        P                  ! V RV 2P	                  4       4      P                  4       R,          pWT RV R2,          pRRV 2R\        R	VR
V/pRo\        \        \        P                  4      ;_uu_ 4        \        P                  ! VP                  RR7      4      oRRR4       \        S\        4      '       dÏ   \        ;QJ d-    V3R lVP!                  4        4       F  '       d   K   RM"	  RM! V3R lVP!                  4        4       4      '       ds   \#        V P$                  TSR,          SR,          SP'                  R. 4       U	u. uF  p	\)        R/ V	B NK  	  up	SR,          SP'                  RR4      4      p
/ SCRR/CpMî\+        WR7      p
V
P,                   U	u. uF  p	\/        V	4      NK  	  pp	/ VCRV
P0                  RV
P2                  RTR\5        V U	u0 uF  q™R,          kK  	  up	4      RV
P6                  RV
P8                  RR/Cp\        \        4      ;_uu_ 4        VP;                  RRR7       VP=                  \        P>                  ! V^R7      R,           RR7       RRR4       Wºn         W«3#   + '       g   i     ELì; iu up	i u up	i u up	i   + '       g   i     L<; i) z–Scan plus attestation dict; the cache (keyed by content digest + source identity) only serves exact
current content under the current scanner version.z.scan-cacheÚ r/  Ú-ú.jsonÚbundle_hashr.  Úscanner_versionr6   r2  Nrá   râ   c              3   óP   <"  € T F  w  rSP                  V4      V8H  x € K  	  R # 5irƒ   )r¨   )r‡   ÚkÚvÚcacheds   &  €r#   rŠ   Ú$scan_skill_cached.<locals>.<genexpr>   s"   øé € Ð'XÑGW¹t¸q¨¯
©
°1«¸Ö(:ÓGWùs   ƒ#&FTr7   r8   r9   r:   r;   r3   Úfresh)r6   Úrulesr   )ÚparentsÚexist_ok)Úindenträ   r!  r'   )!r+  Úparentr#  r$  r)  r&  ÚSCANNER_VERSIONr   rò   ÚjsonÚJSONDecodeErrorÚloadsrï   Ú
isinstancer>   ÚallÚitemsr1   rì   r¨   r   r  r9   r   r8   r7   r'  r:   r;   ÚmkdirÚ
write_textÚdumpsr<   )r  r6   r2  r3  ÚdigestÚ
cache_rootÚsource_identityÚ
cache_fileÚexpectedÚitemÚresultÚ
provenancer9   r>  s   &&$$         @r#   Úscan_skill_cachedrX    s|  ø€ ô ˜ZÓ(€FØ×?Ð?˜j×/Ñ/°-Õ?€JÜ—n’n¨ x¨r°*°Ð%>×%EÑ%EÓ%GÓH×RÑRÓTÐUXÕY€OØ ¨¨/Ð):¸%Ð@Õ@€JØ ¨¨Ð1Ð3DÄoÐW_ÐagØ˜jð*€Hà€FÜ	”'œ4×/Ñ/×	0Õ	0Ü—’˜J×0Ñ0¸+Ð0ÓFÓGˆ÷ 
1ä�&œ$×Ò§C£CÔ'XÀxÇ~Á~ÔGWÓ'X§C§C¢CÔ'XÀxÇ~Á~ÔGWÓ'X×$XÒ$XÜ˜JŸO™O¨V°V¸MÕ5JÈFÐS\ÕL]Ø9?¿¹ÀJÐPRÔ9SÓTÑ9S°œW™_ tœ_Ñ9SÑTÐV\Ð]iÕVjØ"ŸJ™J y°"Ó5ó7ˆð 0˜Ð/ ¨Ñ/‰
ä˜JÔ6ˆØ-3¯_ª_Ó=©_ T”F˜4–L©_ˆÐ=ð@˜ð @ )¨V¯^©^¸]ÈF×L^ÑL^Ð`jÐltØœvÁhÓ&OÁh¸d¨L×'9Ð'9ÁhÑ&OÓPÐR^Ð`f×`qÑ`qØ §¡°¸$ñ@ˆ
ô ”g×ÕØ×Ñ T°DÐÔ9Ø×!Ñ!¤$§*¢*¨ZÀÔ"BÀTÕ"IÐT[Ð!Ô\÷ ð (ÔØÐÐ÷# 
1×	0Ð	0üò Uùò
 >ùâ&Oç×ús+   Â/'J9ÆKÇKÈKÉ$AKÊ9K
	ËK,	c                ó^   € V ^8„  d   QhR\         R\        R\        \        \        3,          /# )r   rV  ÚforcerC   )r1   Úboolr¡   r   )r!   s   "r#   r$   r$   2  s0   € ÷ }ñ }¤ð }´Dð }ÄUÌ4ÔQTÈ9ÕEUñ }r&   c                óv  € \         P                  V P                  \         R,          4      \        P                  V P                  ^4      ,          p\        V P                  4      pV P                  R8H  ;'       d    V P                  R9   pVR8X  d    RRV P                   RV P                   R23# V'       d   V'       g   RRV P                   R	V R
23# VR8X  d#   RRV P                   RV P                   RV R
23# RV P                   RV P                   RV R2pRYT'       d
   R,           3# R,           3# )z®``(allowed, reason)`` from verdict + trust; *force* overrides every block except a dangerous verdict on
community/trusted sources. ``allowed`` is None when policy says "ask".r   r   ÚallowTz	Allowed (z	 source, z	 verdict)zForce-installed despite z
 verdict (z
 findings)ÚaskNzRequires confirmation (z
 source + z
 verdict, z	Blocked (z findings). Fz.--force does not override a dangerous verdict.zUse --force to override.)r   r   )ÚINSTALL_POLICYr¨   r7   ÚVERDICT_INDEXr8   rÉ   r9   )rV  rZ  ÚdecisionÚnÚ
hard_blockÚblockeds   &&    r#   Úshould_allow_installre  2  sA  € ô ×!Ñ! &×"4Ñ"4´nÀ[Õ6QÓRÔS`×SdÑSdÐek×esÑesÐuvÓSwÕx€HÜˆF�O‰OÓ€AØ—‘ ;Ñ.×aÐa°6×3EÑ3EÐIaÑ3a€JØ�7ÔØ�y ×!3Ñ!3Ð 4°I¸f¿n¹nÐ=MÈYÐWÐWÐWß—ZØÐ/°·±Ð/?¸zÈ!ÈÈJÐWÐWÐWØ�5ÔØÐ.¨v×/AÑ/AÐ.BÀ*ÈVÏ^É^ÐL\Ð\fÐghÐfiÐisÐtÐtÐtØ˜&×,Ñ,Ð-¨Z¸¿¹Ð7GÀzÐRSÐQTÐT`Ða€GØ�'ÖQ[ÐMÕ|Ð|Ð|Ða{Õ|Ð|Ð|r&   c                ó0   € V ^8„  d   QhR\         R\        /# )r   rV  rC   )r1   r   )r!   s   "r#   r$   r$   B  s   € ÷ Cñ Cœzð C¬cñ Cr&   c                óÒ  a€ RV P                    RV P                   RV P                   RV P                  P	                  4        2.pV P
                  '       dÕ   R^ R^R^R^/o\        V P
                  V3R	 lR
7       Fš  pVP                  RVP                  P	                  4       P                  ^4       RVP                  P                  ^4       RVP                   RVP                   2P                  ^4       RVP                  R,           R2	4       Kœ  	  VP                  R4       \        V 4      w  r4VRJ d   RMVf   RMRpRP                  VRV RV 2.,           4      # )uQ   Compact multi-line report for CLI/chat display; findings sorted critical â†’ low.zScan: rë   Ú/z)  Verdict: rO   rQ   r  r£   c                 ó<   <€ SP                  V P                  ^4      # )é   )r¨   r   )r   Úorders   &€r#   Ú<lambda>Ú$format_scan_report.<locals>.<lambda>G  s   ø€ °u·y±yÀÇÁÈQÔ7Or&   )Úkeyz  rÆ   Ú:z ":Né<   NÚ"r3   TÚALLOWEDzNEEDS CONFIRMATIONÚBLOCKEDrä   z
Decision: õ    â€” )r5   r6   r7   r8   Úupperr9   r'  r�   r   Úljustr   r   r   r   re  rÊ   )rV  r€   r   ÚallowedÚreasonÚstatusrk  s   &     @r#   Úformat_scan_reportrz  B  sO  ø€ à�f×'Ñ'Ð(¨¨6¯=©=¨/¸¸6×;MÑ;MÐ:NÈlÐ[a×[iÑ[i×[oÑ[oÓ[qÐZrÐsÐt€EØ‡‡€Ø˜Q ¨¨8°Q¸¸qÐAˆÜ˜Ÿ™Ô-O×PˆAØ�L‰L˜2˜aŸj™j×.Ñ.Ó0×6Ñ6°qÓ9Ð:¸!¸A¿J¹J×<LÑ<LÈRÓ<PÐ;QÐQRØ Ÿv™v˜h a¨¯© xÐ0×6Ñ6°rÓ:Ð;¸3¸q¿w¹wÀs½|¸nÈBðPö Qñ Qð 	�‰�RÔÜ*¨6Ó2�O€GØ! T›/‰YÀwÂÑ/CÐ\e€FØ�9‰9�U 
¨6¨(°%¸°xÐ@ÐAÕAÓBÐBr&   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   Ú	skill_dirrC   )r
   r=   r   )r!   s   "r#   r$   r$   P  s   € ÷ *ñ *¤ð *´d¼7µmñ *r&   c                ó˜  a€ . oV3R lp^ ;r4V P                  R4       EF”  p\        VP                  V 4      4      pVP                  4       '       g   VP	                  4       '       d   Ve   V! V4      '       d   K^  V^,          pVP	                  4       '       dI    VP                  4       pVP                  V P                  4       4      '       g   V! RRRVRV 2R4       KÅ   VP                  4       pYHP                  ;p	,          pT	\        R,          8”  d)   T! RR	RYiR,           R2RT	R,           R\         R24       TP                  P                  4       ;p
\        9   d   T! RRRTRT
 2RT
 R24       T
\        9  g   EKk  TP                  ^I,          '       g   EK‡  T! RR	RTRR4       EK—  	  V\         8”  d   V! RR	RRV R2RV R\          R24       V\"        R,          8”  d*   V! R R!RRVR,           R"2R#VR,           R$\"         R24       S#   \         d    T! RR	RTR
R4        ELTi ; i  \         d     EK*  i ; i)%z˜Structural anomalies (counts, sizes, binaries, stray executables, escaping symlinks); *ignore(rel) -> bool*
excludes paths from every count and finding.c                 óB   <€ SP                  \        WW#^ WE4      4       R# )é    N)r�   r   )rž   ÚsevÚcatr  r   Údescr9   s   &&&&&&€r#   r¼   Ú_check_structure.<locals>.addU  s   ø€ Ø�‰œ ¨#°A°uÓCÖDr&   r	  Úsymlink_escaperO   Ú	traversalzsymlink -> z*symlink points outside the skill directoryÚbroken_symlinkr  zbroken symlinkzbroken or circular symlinki   Úoversized_fileÚ
structuralÚKBzfile is zKB (limit: zKB)Úbinary_filezbinary: zbinary/executable file (z) should not be in a skillÚunexpected_executablezexecutable bit setzBfile has executable permission but is not a recognized script typeÚtoo_many_filesz(directory)z filesz
skill has z files (limit: rj   Úoversized_skillr£   zKB totalz	skill is zKB total (limit: )r  r   r  r  Ú
is_symlinkÚresolveÚis_relative_torò   ÚstatÚst_sizeÚMAX_SINGLE_FILE_KBr    rí   ÚSUSPICIOUS_BINARY_EXTENSIONSÚ_SCRIPT_EXTENSIONSÚst_modeÚMAX_FILE_COUNTÚMAX_TOTAL_SIZE_KB)r|  r  r¼   Ú
file_countÚ
total_sizer   r  ÚresolvedÚstÚsizeÚextr9   s   &&         @r#   r  r  P  sb  ø€ ð €HõEàÐ€JØ�_‰_˜S×!ˆÜ�!—-‘- 	Ó*Ó+ˆØ—	‘	—’˜qŸ|™|Ÿ~š~°6Ò3EÉ&ÐQTÏ+Ê+ÙØ�a�ˆ
Ø�<‰<�>Š>ðrØŸ9™9›;�Ø×.Ñ.¨y×/@Ñ/@Ó/B×CÒCÙÐ(¨*°kÀ3È+ÐV^ÐU_ÐH`ØDôFñ ð	Ø—‘“ˆBð 	Ÿz™zÐ)�tÕ*ˆ
ØÔ$ tÕ+Ô+ÙÐ  (¨L¸#È$Å,ÀÈrÐ?RØ˜4 4�<˜.¨Ô4FÐ3GÀsÐKôMà—8‘8—>‘>Ó#Ð#ˆCÔ(DÔDÙ�˜z¨<¸ÀÈÈÐ>NØ*¨3¨%Ð/IÐJôLàÔ(×(¨R¯Z©Z¸%×-?×-?ÙÐ'¨°<ÀÐFZØT÷Vñ5 "ð8 ”NÔ"ÙÐ˜h¨°mÈ
À|ÐSYÐEZØ˜˜ O´NÐ3CÀ1ÐEô	GàÔ%¨Õ,Ô,ÙÐ˜u l°MÀjÐTXÕFXÐEYÐYaÐCbØ˜
 dÕ*Ð+Ð+<Ô=NÐ<OÈsÐSô	Uà€Oøô/ ô rÙÐ$ h°¸SÐBRÐTp×qðrûô
 ô 	Ûð	ús*   Â4HÃHÃ$H9ÈH6È5H6È9I	ÉI	c                ó$   € V ^8„  d   QhR\         /# )r   r|  r	   )r!   s   "r#   r$   r$   �  s   € ÷ #ñ #¤$ñ #r&   c                óˆ  a a€ . oV 3R l\          4        FŒ  p\        \        \        4      ;_uu_ 4        VP	                  4       '       dO   SP                  R \        \        P                  VP                  RR7      P                  4       4       4       4       RRR4       KŽ  	  R V3R llpV#   + '       g   i     K¬  ; i)aY  Build ``ignore(rel_posix_path) -> bool`` from `.skillignore` / `.clawhubignore`. gitignore basics: blank
lines and ``#`` comments skipped; trailing ``/`` = directory (it and everything under it); ``*``/``?`` globs via
fnmatch on the full path and each segment; leading ``/`` anchors to the root. Ignore files always excluded;
``SKILL.md`` never.c              3   ó6   <"  € T F  pSV,          x € K  	  R # 5irƒ   r'   )r‡   rì   r|  s   & €r#   rŠ   Ú%_load_skill_ignore.<locals>.<genexpr>‡  s   øé € ÐDÑ,C Dˆy˜4×ÒÓ,Cùs   ƒc              3   ól   "  € T F*  pV'       g   K  VP                  R 4      '       d   K&  Vx € K,  	  R# 5i)rm   N©r¦   )r‡   Úss   & r#   rŠ   r¢  Š  s.   é € ð  @Ñ+j aÜ#$ô !"Ø-.¯\©\¸#×->÷ !"¢Ó+jùs   ‚
4‘4ª
4rá   râ   Nc                ó0   € V ^8„  d   QhR\         R\        /# )r   r  rC   )r   r[  )r!   s   "r#   r$   Ú(_load_skill_ignore.<locals>.__annotate__�  s   € ÷ ñ ”Cð œDñ r&   c                 ó  <a€ \        V 4      P                  4       pVP                  R 4      pVR,          pVR8X  d   R# V\        9   d   R# S EF8  pVP	                  R 4      pVP                  R 4      oS'       g   K0  VP	                  SR ,           4      pVP                  R 4      '       dB   VS8X  g4   V'       g,   V'       g)   R S,           R ,           R V,           R ,           9   d    R# Kž  K   \        P                  ! VS4      '       g|   V'       d   KÇ  \        P                  ! VS4      '       gU   V'       gM   R S9  g   Kõ  \        ;QJ d    V3R lV 4       F  '       g   K   RM	  RM! V3R lV 4       4      '       g   EK8   R# 	  R# )rh  rà   FTc              3   óR   <"  € T F  p\         P                   ! VS4      x € K  	  R # 5irƒ   )Úfnmatch)r‡   Úsegr  s   & €r#   rŠ   Ú5_load_skill_ignore.<locals>.ignore.<locals>.<genexpr>   s   øé € Ð(QÉDÀS¬¯ª¸¸a×)@Ð)@ËDùs   ƒ$'rÇ   )	r
   r  rð   Ú_SKILL_IGNORE_FILENAMESr¦   r×   r–   rª  r»   )	r  Ú	rel_posixÚsegsÚbaseÚpatÚanchoredÚbelowr  Úpatternss	   &      @€r#   r  Ú"_load_skill_ignore.<locals>.ignore�  s  ù€ Ü˜“I×&Ñ&Ó(ˆ	Ø�‰˜sÓ#ˆØ�B�xˆØ�:ÔÙØÔ*Ô*ÙÜˆCØ—~‘~ cÓ*ˆHØ—	‘	˜#“ˆAßÙØ×(Ñ(¨¨S­Ó1ˆEØ�|‰|˜C× Ò Ø ”>§U·8ÀÀqÅÈ3ÅÐTWÐZcÕTcÐfiÕTiÔ@jÚñ Ak±8ô —’ ¨A×.Ò.·x±xÄWÇ_Â_ÐUYÐ[\×E]ÒE]×afØ˜q–L§S£SÔ(QÉDÓ(Q§S§S¢SÔ(QÉDÓ(Q×%QÕ%QÚñ ñ r&   )r­  r   rñ   rò   r  r  Úmapr   r×   rï   Ú
splitlines)r|  Úigr  r´  s   f  @r#   r  r  �  s”   ù€ ð
 €HÜDÕ,CÖDˆÜÔ(¬'×2Õ2Ø�z‰z�|Š|Ø—‘ñ  @¬3¬s¯y©y¸"¿,¹,ÐP[¸,Ó:\×:gÑ:gÓ:iÔ+jó  @ô @÷ 3Ñ2ñ E÷ð ð. €M÷9 3×2Ð2ús   ´A%B0Â0Cc                ó0   € V ^8„  d   QhR\         R\         /# )r   r6   rC   rD   )r!   s   "r#   r$   r$   ª  s   € ÷ iñ i¤ð i¬ñ ir&   c                ó  a a€ S \        \        V 3R l\         4       R4      4      R oSR8X  d   R# SR8X  d   R# \        ;QJ d#    V3R l\         4       F  '       g   K   RM	  R	M! V3R l\         4       4      '       d   R
# R# )uÒ   Source id -> trust level. "official" is provenance, not a user-controlled GitHub id like "official/<repo>";
trusted repos match exactly or as a skill path inside the repo â€” never a sibling sharing the prefix.c              3   óZ   <"  € T F   pSP                  V4      '       g   K  Vx € K"  	  R # 5irƒ   r¤  )r‡   r  r6   s   & €r#   rŠ   Ú'_resolve_trust_level.<locals>.<genexpr>­  s#   øé € ÐUÑ&< À×@QÑ@QÐRS×@TŸ1š1Ó&<ùs   ƒ+¡
+r3   Nr   Úofficialr   c              3   óf   <"  € T F&  pSV8H  ;'       g    SP                  V R 24      x € K(  	  R# 5i)rh  Nr¤  )r‡   ÚtÚsrcs   & €r#   rŠ   r¼  ²  s/   øé € ÐWÉÀA˜C 1™H×?Ð?¨¯©¸!¸¸A°wÓ(?Ô?Ëùs   ƒ1”1TFr   r   )rÉ   rõ   Ú_SOURCE_PREFIX_ALIASESr»   ÚTRUSTED_REPOS)r6   rÀ  s   f@r#   r
  r
  ª  sh   ù€ ð ””TÔUÕ&<ÓUÐWYÓZÓ[Ð\Ð
]€CØ
ˆoÔÙØ
ˆjÔÙß›ÔWÍÓWŸŸšÔWÍÓW×WÒWˆ9ÐhÐ]hÐhr&   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r   r9   rC   )r=   r   r   )r!   s   "r#   r$   r$   µ  s"   € ÷ Xñ X¤¤g¥ð X´3ñ Xr&   c                óh   € V  Uu0 uF  qP                   kK  	  ppRV9   d   R# RV9   d   R# R# u upi )uT   critical â†’ dangerous, high â†’ caution; medium/low alone are informational (safe).rO   r   rQ   r   r   )r   )r9   r   r€  s   &  r#   r  r  µ  s;   € á'Ó
(™x˜!�:Œ:™x€CÐ
(Ø$¨Ô+ˆ;ÐW¸fÈ¼m°ÐWÐQWÐWùò )s   …/c                óv   € V ^8„  d   QhR\         R\         R\         R\         R\        \        ,          R\         /# )r   rì   r6   r  r8   r9   rC   )r   r=   r   )r!   s   "r#   r$   r$   »  sD   € ÷ vñ vœð v¤cð v´#ð vÄð vÌtÔT[Í}ð vÔadñ vr&   c                 ó´   € V'       g   V  R 2# T  RT R\        V4       RRP                  \        V Uu0 uF  qUP                  kK  	  up4      4       2# u upi )z!: clean scan, no threats detectedz: rt  z finding(s) in z, )rÉ   rÊ   r'  r   )rì   r6   r  r8   r9   r   s   &&&&& r#   r  r  »  s]   € ßØ�Ð8Ð9Ð9ØˆV�2�g�Y˜e¤C¨£M ?°/À$Ç)Á)ÌFÑhpÓSqÑhpÐcd×T^ÔT^ÑhpÑSqÓLrÓBsÐAtÐuÐuùÒSqs   ´A>   úNVIDIA/skillsúopenai/skillsúanthropics/skillsúhuggingface/skills)r]  r]  r]  )r]  r]  Úblock)r]  rË  rË  )r]  r]  r^  )zvcurl\s+(?![^\n]*https?://(?:localhost|127\.0\.0\.1|\[::1\]))[^\n]*\$\{?\w*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)S?\bÚenv_exfil_curlrO   rP   z6curl command interpolating secret environment variable)zvwget\s+(?![^\n]*https?://(?:localhost|127\.0\.0\.1|\[::1\]))[^\n]*\$\{?\w*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)S?\bÚenv_exfil_wgetrO   rP   z6wget command interpolating secret environment variable)znfetch\s*\((?![^\n]*https?://(?:localhost|127\.0\.0\.1|\[::1\]))[^\n]*\$\{?\w*(?:KEY|TOKEN|SECRET|PASSWORD)S?\bÚenv_exfil_fetchrO   rP   z6fetch() call interpolating secret environment variable)zwhttpx?\.(get|post|put|patch)\s*\((?![^\n]*https?://(?:localhost|127\.0\.0\.1|\[::1\]))[^\n]*(KEY|TOKEN|SECRET|PASSWORD)Úenv_exfil_httpxrO   rP   z&HTTP library call with secret variable)zyrequests\.(get|post|put|patch)\s*\((?![^\n]*https?://(?:localhost|127\.0\.0\.1|\[::1\]))[^\n]*(KEY|TOKEN|SECRET|PASSWORD)Úenv_exfil_requestsrO   rP   z*requests library call with secret variable)zbase64[^\n]*envÚencoded_exfilrQ   rP   z0base64 encoding combined with environment access)z\$HOME/\.ssh|\~/\.sshÚssh_dir_accessrQ   rP   zreferences user SSH directory)z\$HOME/\.aws|\~/\.awsÚaws_dir_accessrQ   rP   z)references user AWS credentials directory)z\$HOME/\.gnupg|\~/\.gnupgÚgpg_dir_accessrQ   rP   zreferences user GPG keyring)z\$HOME/\.kube|\~/\.kubeÚkube_dir_accessrQ   rP   z&references Kubernetes config directory)z\$HOME/\.docker|\~/\.dockerÚdocker_dir_accessrQ   rP   z5references Docker config (may contain registry creds))z'\$HOME/\.hermes/\.env|\~/\.hermes/\.envÚhermes_env_accessrO   rP   z'directly references Hermes secrets file)zFcat\s+(?!>)[^\n]*(\.env|credentials|\.netrc|\.pgpass|\.npmrc|\.pypirc)Úread_secrets_filerO   rP   zreads known secrets file)z3printenv|(?<![A-Za-z0-9_])env\s*\|(?!\|)(?!\s*[{(])Údump_all_envrQ   rP   zdumps all environment variables)z&^[^#\n]*os\.environ\b(?!\s*\.get\s*\()Úpython_os_environrQ   rP   zDaccesses os.environ outside comments/docstrings (potential env dump))zOos\.environ\s*\.get\s*\(\s*["\'][^"\']*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)Úpython_environ_get_secretr  rP   zHreads secret via os.environ.get() (normal API-key access; informational))z@os\.getenv\s*\(\s*[^\)]*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)Úpython_getenv_secretr  rP   zCreads secret via os.getenv() (normal API-key access; informational))zprocess\.env\[Únode_process_envrQ   rP   z*accesses process.env (Node.js environment))z*(?-i:ENV)\[.*(?:KEY|TOKEN|SECRET|PASSWORD)Úruby_env_secretrO   rP   zreads secret via Ruby ENV[])al  (?<![-/])\b(?:dig|nslookup)\s+(?:[-+@]\S*(?:\s+[^\s$"\'-][^\s$]*)?\s+)*["\']?[^\s"\'$()]*\$(?:\{[^}\s]*\}|\([^\n]*?\)+|\w+)[\w-]*["\']?\.[a-z]|(?<![-/])\bhost\s+(?:[-+@]\S*(?:\s+[^\s$"\'-][^\s$]*)?\s+)*["\']?[^\s"\'$()]*\$(?:\{[^}\s]*\}|\([^\n]*?\)+|\w+)[\w-]*\.[a-z]|(?:^|[;&|]|\$\(|\b(?:do|then|else)\b)\s*host\s+(?:[-+@]\S*(?:\s+[^\s$"\'-][^\s$]*)?\s+)*["\']?\$Ú	dns_exfilrO   rP   zBDNS lookup with variable interpolation (possible DNS exfiltration))z,>\s*/tmp/[^\s]*\s*&&\s*(curl|wget|nc|python)Útmp_stagingrO   rP   zwrites to /tmp then exfiltrates)z!\[.*\]\(https?://[^\)]*\$\{?Úmd_image_exfilrQ   rP   zBmarkdown image URL with variable interpolation (image-based exfil))z\[.*\]\(https?://[^\)]*\$\{?Úmd_link_exfilrQ   rP   z)markdown link with variable interpolation)z=ignore\s+(?:\w+\s+)*(previous|all|above|prior)\s+instructionsÚprompt_injection_ignorerO   rê   z.prompt injection: ignore previous instructions)zyou\s+are\s+(?:\w+\s+)*now\s+Úrole_hijackrQ   rê   z%attempts to override the agent's role)z�do\s+not\s+(?:\w+\s+)*tell\s+(?:\w+\s+)*the\s+user(?!\s+to\s+["\'\u201c\u2018])(?!.*\b(?:unless|except|until|confirm|diagnos\w*|verify|check)\b)Údeception_hiderQ   rê   z-instructs agent to hide information from user)z0system\s+(?:\w+\s+)*prompt\s+(?:\w+\s+)*overrideÚsys_prompt_overriderO   rê   z&attempts to override the system prompt)z+pretend\s+(?:\w+\s+)*(you\s+are|to\s+be)\s+Úrole_pretendrQ   rê   z6attempts to make the agent assume a different identity)zRdisregard\s+(?:\w+\s+)*(your|all|any)\s+(?:\w+\s+)*(instructions|rules|guidelines)Údisregard_rulesrO   rê   z&instructs agent to disregard its rules)z-output\s+(?:\w+\s+)*(system|initial)\s+promptÚleak_system_promptrQ   rê   z%attempts to extract the system prompt)z.(when|if)\s+no\s*one\s+is\s+(watching|looking)Úconditional_deceptionrQ   rê   z=conditional instruction to behave differently when unobserved)zwact\s+as\s+(if|though)\s+(?:\w+\s+)*you\s+(?:\w+\s+)*(have\s+no|don\'t\s+have)\s+(?:\w+\s+)*(restrictions|limits|rules)Úbypass_restrictionsrO   rê   z+instructs agent to act without restrictions)z5translate\s+.*\s+into\s+.*\s+and\s+(execute|run|eval)Útranslate_executerO   rê   z(translate-then-execute evasion technique)ah  <!--[^>]*(?:\b(?:ignore|forget|disregard|override)\s+(?:\w+\s+)*?(?:previous|prior|above|earlier|all|any|your|the)\s+(?:\w+\s+)*?(?:instructions?|rules|prompts?|guidelines|directions|restrictions)|\bsystem\s*(?:prompt|message|instructions?|override)|\b(?:override|secret|hidden|system)\s*:|\b(?:ignore|override|bypass|disable)\s+(?:\w+\s+)*?(?:safety|security|guardrails|filters)\b|\b(?:secret|hidden|new)\s+(?:instructions?|commands?|directives?|tasks?)\b|\byou\s+are\s+now\b|\bdo\s+not\s+(?:tell|reveal|show|mention|inform)\b|\b(?:note|message)\s+(?:to|for)\s+(?:the\s+)?(?:ai|agent|assistant|model|llm)\b)[^>]*-->Úhtml_comment_injectionrQ   rê   z$hidden instructions in HTML comments)z5<\s*div\s+style\s*=\s*["\'][\s\S]*?display\s*:\s*noneÚ
hidden_divrQ   rê   z(hidden HTML div (invisible instructions))a	  rm\s+-rf\s+((?:[^\s;&|<>#][^\s;&|<>]*\s+)+?)?/(?(1)(?!/(?:\s|$)))(?:(?!(?:tmp|var/tmp|dev/shm|run|var/lib/apt/lists|var/cache/(?:apt|apk|yum|dnf))(?:\b|/))|(?:tmp|var/tmp|dev/shm|run|var/lib/apt/lists|var/cache/(?:apt|apk|yum|dnf))/(?:[^/\s]*/)*\.\.(?=/|[\s;&|]|$))Údestructive_root_rmrO   Údestructivezrecursive delete from root)zg(?<![A-Za-z0-9])rm\s+(-[^\s]*)?r.*(?:\$HOME|~[/\s*]|~$)|(?<![A-Za-z0-9])rmdir\s+.*(?:\$HOME|~[/\s*]|~$)Údestructive_home_rmrO   rð  z6recursive delete targeting home directory ($HOME or ~))zchmod\s+777Úinsecure_permsr  rð  zsets world-writable permissions)z	>\s*/etc/Úsystem_overwriterO   rð  z$overwrites system configuration file)z\bmkfs\bÚformat_filesystemrO   rð  zformats a filesystem)z\bdd\s+.*if=.*of=/dev/Údisk_overwriterO   rð  zraw disk write operation)zshutil\.rmtree\s*\(\s*[\"\'/]Úpython_rmtreerQ   rð  z/Python rmtree on absolute or root-relative path)ztruncate\s+-s\s*0\s+/Útruncate_systemrO   rð  z#truncates system file to zero bytes)z\bcrontab\bÚpersistence_cronr  rT   zmodifies cron jobs)z:\.(bashrc|zshrc|bash_profile|bash_login|zprofile|zlogin)\bÚshell_rc_modr  rT   úreferences shell startup file)z(?<![\w)\]?])\.profile\brù  r  rT   rú  )Úauthorized_keysÚssh_backdoorrO   rT   zmodifies SSH authorized keys)z
ssh-keygenÚ
ssh_keygenr  rT   zgenerates SSH keys)z-systemd.*\.service|systemctl\s+(enable|start)Úsystemd_servicer  rT   z%references or enables systemd service)z/etc/init\.d/Úinit_scriptr  rT   z references init.d startup script)z+launchctl\s+load|LaunchAgents|LaunchDaemonsÚmacos_launchdr  rT   z%macOS launch agent/daemon persistence)z/etc/sudoers|visudoÚsudoers_modrO   rT   z'modifies sudoers (privilege escalation))zgit\s+config\s+--global\s+Úgit_config_globalr  rT   z!modifies global git configuration)z^\bnc\s+-[lp]|ncat\s+-[lp]|\bsocat\b[^\n]*\b(?:tcp|udp|openssl|ssl|exec|system|pty|unix)[\w-]*:Úreverse_shellrO   rU   z potential reverse shell listener)z4\bngrok\b|\blocaltunnel\b|\bserveo\b|\bcloudflared\bÚtunnel_servicerQ   rU   z*uses tunneling service for external access)z*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{2,5}Úhardcoded_ip_portr  rU   zhardcoded IP address with port)z0\.0\.0\.0:\d+|INADDR_ANYrV   rQ   rU   zbinds to all network interfaces)z'python[23]?\s+-c\s+["\']import\s+socketÚpython_socket_onelinerrO   rU   z9Python one-liner socket connection (likely reverse shell))zsocket\.connect\s*\(\s*\(Úpython_socket_connectrQ   rU   z'Python socket connect to arbitrary host)z9webhook\.site|requestbin\.com|pipedream\.net|hookbin\.comÚexfil_servicerQ   rU   z:references known data exfiltration/webhook testing service)z&pastebin\.com|hastebin\.com|ghostbin\.Úpaste_servicer  rU   z0references paste service (possible data staging))aµ  (?:\bbase64\s+(?:-[^\s|]+\s+)*?(?:-[a-z]*d[a-z]*|--decode)\b|\bopenssl\s+(?:base64|enc)\b[^|;&\n]*?\s-d\b)[^\n]*?(?:\||;|&&)\s*(?:\w+=\S*\s+)*(?:\S*/)?(?:sh|bash|zsh|ksh|dash|fish|python[\d.]*|perl|ruby|node|nodejs|php|eval|source|exec|xargs|env|sudo|iex|pwsh|powershell|tar|bsdtar|unzip|cpio|gunzip|gzip|zcat|xz|unxz|bunzip2|\.(?=\s))(?![\w.-])|\b(?:eval|source|iex|exec)\b[^\n]*\bbase64\s+(?:-[^\s|]+\s+)*?(?:-[a-z]*d[a-z]*|--decode)\bÚbase64_decode_piperQ   rX   z%base64 decodes and pipes to execution)z7\\x[0-9a-fA-F]{2}.*\\x[0-9a-fA-F]{2}.*\\x[0-9a-fA-F]{2}Úhex_encoded_stringr  rX   z)hex-encoded string (possible obfuscation))z\beval\s*\(\s*["\']Úeval_stringrQ   rX   zeval() with string argument)z°(?<![.\w])exec\s*\(\s*["\'](?!(?-i:PRAGMA|BEGIN|COMMIT|ROLLBACK|CREATE|INSERT|SELECT|UPDATE|DELETE|DROP|ALTER|VACUUM|SAVEPOINT|RELEASE|ANALYZE|REINDEX|ATTACH|DETACH|REPLACE)\b)Úexec_stringrQ   rX   zexec() with string argument)z?compile\s*\(\s*[^\)]+,\s*["\'].*["\']\s*,\s*["\']exec["\']\s*\)Úpython_compile_execrQ   rX   zPython compile() with exec mode)zgetattr\s*\(\s*__builtins__Úpython_getattr_builtinsrQ   rX   z5dynamic access to Python builtins (evasion technique))z#__import__\s*\(\s*["\']os["\']\s*\)Úpython_import_osrQ   rX   zdynamic import of os module)zcodecs\.decode\s*\(\s*["\']Úpython_codecs_decoder  rX   z6codecs.decode (possible ROT13 or encoding obfuscation))zString\.fromCharCode|charCodeAtÚjs_char_coder  rX   z=JavaScript character code construction (possible obfuscation))zatob\s*\(|btoa\s*\(Ú	js_base64r  rX   zJavaScript base64 encode/decode)z\[::-1\]Ústring_reversalr£   rX   z-string reversal (possible obfuscated payload))z)chr\s*\(\s*\d+\s*\)\s*\+\s*chr\s*\(\s*\d+Úchr_buildingrQ   rX   z.building string from chr() calls (obfuscation))z7\\u[0-9a-fA-F]{4}.*\\u[0-9a-fA-F]{4}.*\\u[0-9a-fA-F]{4}Úunicode_escape_chainr  rX   z/chain of unicode escapes (possible obfuscation))z.subprocess\.(run|call|Popen|check_output)\s*\(Úpython_subprocessr  Ú	executionzPython subprocess execution)zos\.system\s*\(Úpython_os_systemrQ   r  u)   os.system() â€” unguarded shell execution)zos\.popen\s*\(Úpython_os_popenrQ   r  u#   os.popen() â€” shell pipe execution)z%child_process\.(exec|spawn|fork)\s*\(Únode_child_processrQ   r  zNode.js child_process execution)zRuntime\.getRuntime\(\)\.exec\(Újava_runtime_execrQ   r  u'   Java Runtime.exec() â€” shell execution)z`[^`]*\$\([^)]+\)[^`]*`Úbacktick_subshellr  r  z)backtick string with command substitution)z!`[^`\s][^`\n]*`Úinline_shell_execrQ   r  zGinline-shell auto-exec snippet (expands via bash -c on skill view/load))z\.\./\.\./\.\.rZ   rQ   r…  z+deep relative path traversal (3+ levels up))z	\.\./\.\.r[   r  r…  z&relative path traversal (2+ levels up))z/etc/passwd|/etc/shadowÚsystem_passwd_accessrO   r…  z references system password files)z/proc/self|/proc/\d+/Úproc_accessrQ   r…  z3references /proc filesystem (process introspection))z	/dev/shm/Údev_shmr  r…  z.references shared memory (common staging area))z.xmrig|stratum\+tcp|monero|coinhive|cryptonightÚcrypto_miningrO   Úminingzcryptocurrency mining reference)zhashrate|nonce.*difficultyÚmining_indicatorsr  r#  z)possible cryptocurrency mining indicators)z#\s*///\s*script.*dependenciesÚpep723_inline_depsr  r]   zAPEP 723 inline script metadata with dependencies (verify pinning))z pip\s+install\s+(?!-r\s)(?!.*==)Úunpinned_pip_installr  r]   z#pip install without version pinning)znpm\s+install\s+(?!.*@\d)Úunpinned_npm_installr  r]   z#npm install without version pinning)zuv\s+run\s+Úuv_runr  r]   z/uv run (may auto-install unpinned dependencies))zD(curl|wget|httpx?\.get|requests\.get|fetch)\s*[\(]?\s*["\']https?://Úremote_fetchr  r]   z"fetches remote resource at runtime)zgit\s+clone\s+Ú	git_cloner  r]   z"clones a git repository at runtime)zdocker\s+pull\s+Údocker_pullr  r]   zpulls a Docker image at runtime)z^allowed-tools\s*:Úallowed_tools_fieldr£   Úprivilege_escalationzBskill declares allowed-tools (standard frontmatter; informational))z\bsudo\b(?!\.\w)ra   rQ   r-  z uses sudo (privilege escalation))zx(?<![a-z])set(?:e|re|res)?[ug]id\s*\(|\bcap_set[ug]id\b|\bchmod\s+(?:-\w+\s+)*(?:[ugoa]*[+=][rwxXt]*s|0?[2-7][0-7]{3}\b)Úsetuid_setgidrO   r-  z.setuid/setgid (privilege escalation mechanism))z(?<!cap_)set[ug]id(?!\s*\()r.  r  r-  z&mentions setuid/setgid (informational))ÚNOPASSWDÚnopasswd_sudorO   r-  z:NOPASSWD sudoers entry (passwordless privilege escalation))zchmod\s+[u+]?sÚsuid_bitrO   r-  zsets SUID/SGID bit on a file)z0AGENTS\.md|CLAUDE\.md|\.cursorrules|\.clinerulesÚagent_config_refr£   rT   zQreferences agent config files (informational; only modification intent is scored))z'\.hermes/config\.yaml|\.hermes/SOUL\.mdÚhermes_config_refr£   rT   zYreferences Hermes configuration files (informational; only modification intent is scored))z \.claude/settings|\.codex/configÚother_agent_config_refr£   rT   z^references other agent configuration files (informational; only modification intent is scored))zu(?:api[_-]?key|token|secret|password)\s*[=:]\s*["\'](?!(?-i:[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+)["\'])[A-Za-z0-9+/=_-]{20,}Úhardcoded_secretrO   Úcredential_exposurez,possible hardcoded API key, token, or secret)z.(?-i:-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----)Úembedded_private_keyrO   r6  zembedded private key)z6(?-i:ghp_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9_]{80,})Úgithub_token_leakedrO   r6  z-GitHub personal access token in skill content)z(?-i:sk-[A-Za-z0-9]{20,})Úopenai_key_leakedrO   r6  z(possible OpenAI API key in skill content)z(?-i:sk-ant-[A-Za-z0-9_-]{90,})Úanthropic_key_leakedrO   r6  z+possible Anthropic API key in skill content)z(?-i:AKIA[0-9A-Z]{16})Úaws_access_key_leakedrO   r6  z"AWS access key ID in skill content)z(?-i:glpat-[A-Za-z0-9_\-]{20,})Úgitlab_token_leakedrO   r6  z-GitLab personal access token in skill content)z"\bDAN\s+mode\b|Do\s+Anything\s+NowÚjailbreak_danrO   rê   z'DAN (Do Anything Now) jailbreak attempt)z"\bdeveloper\s+mode\b.*\benabled?\bÚjailbreak_dev_moderO   rê   z developer mode jailbreak attempt)z3hypothetical\s+scenario.*(?:ignore|bypass|override)Úhypothetical_bypassrQ   rê   z1hypothetical scenario used to bypass restrictions)z$for\s+educational\s+purposes?\s+onlyÚeducational_pretextr  rê   z9educational pretext often used to justify harmful content)zW(respond|answer|reply)\s+without\s+(?:\w+\s+)*(restrictions|limitations|filters|safety)Úremove_filtersrO   rê   z1instructs agent to respond without safety filters)z>you\s+have\s+been\s+(?:\w+\s+)*(updated|upgraded|patched)\s+toÚfake_updaterQ   rê   z3fake update/patch announcement (social engineering))zYnew\s+(?:\w+\s+)*policy|updated\s+(?:\w+\s+)*guidelines|revised\s+(?:\w+\s+)*instructionsÚfake_policyr  rê   z8claims new policy/guidelines (may be social engineering))z6(send|post|upload|transmit)\s+.*\s+(to|at)\s+https?://Úsend_to_urlrQ   rP   z%instructs agent to send data to a URL>   rü  rÓ  rÔ  rÒ  rÕ  rÖ  r  )rm   Ú;)r{   rm   >   rr   rs   rz   rå   rq   rl   rp   rn   r|   rx   ú.cssry   r}   ú.texú.txtú.xmlru   ro   rw   ú.htmlr8  rv   rt   >   ú.soú.appú.binú.comú.datú.debú.dllú.dmgú.exeú.msiú.rpmú.dylib>   rq   rl   rp   rn   ro   )r3   )r   )Frƒ   )z.skillignorez.clawhubignore)z
skills-sh/z
skills.sh/z	skils-sh/z	skils.sh/)WÚ__doc__Úrerª  r#  rG  Ú
contextlibr   Údataclassesr   r   r   r   r   r   Úpathlibr
   Útypingr   r   rF  rÂ  r_  r`  r   r1   rJ   Ú_AGENT_CONFIG_FILESÚ_HERMES_CONFIG_FILESÚ_OTHER_AGENT_CONFIG_FILESrG   rK   rN   Ú_NO_TRANSFERÚ_SHORT_FILLERÚ_NOT_DELEGATEÚ
_CTX_SCOPEÚ	_CTX_DESTÚ_CTX_DATIVEÚ_SHELL_NAMES_REÚ_SUDO_PREFIXÚ
_CRED_FILEÚ_CRED_FILE_LITERALÚ_PY_CRED_FILE_ARGÚTHREAT_PATTERNSÚcompileÚ
IGNORECASEró   Ú	frozensetr¤   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+  r1  rX  re  rz  r  r­  r  rÁ  r
  r  r  )rù   Úrests   00r#   Ú<module>rp     s˜  ðñfó 
Û Û Û Ý ß 0Ñ 0ß ,Ñ ,Ý ß ð %€ò ^€ð Ð3ØÐ3ØÐ3àÐ1ð€ð ˜˜I q¨+°qÐ9€ð ÷ð ó ðð ÷8ð 8ó ð8ðNð ð NÐ Ø<Ð àGÐ õ	Mõ9õmð K€ð $€ðYð ðIð ð '€	Ø7€ð
 0€Ø*€ð
 D€
ð '¨Õ3Ð6GÕGÐ Ø8Ð;MÕMÐPYÕYÐ ð|ðmð|ðmð|ðnð|ð^ð|ðeð|ð" vð#|ð$ jð%|ð& vð'|ð( lð)|ð* vð+|ð,kð-|ð0að1|ð6Rð7|ð: 5Ð7IÕIØ˜Z¨Ð9cðeð;|ðN Ð*Õ*Ø`õaàõà-õ.à0jõkð ˜Z¨Ð9_ðaðO|ð`Pða|ðlzðm|ðpHðq|ðt~ðu|ðx rðy|ð| Bð}|ð\tð]|ðhSði|ðnuðo|ðr |ðs|ðvkðw|ðz tð{|ðB]ðC|ðH_ðI|ðLdðM|ðP[ðQ|ðTYðU|ðXtðY|ð\dð]|ð`_ða|ðh\ði|ðzTð{|ðPUðQ|ð\qð]|ð` cða|ðb jðc|ðd Zðe|ðf iðg|ðh Bði|ðj tðk|ðn Xðo|ðzOð{|ð~Oð|ðB dðC|ðD QðE|ðFZðG|ðJ cðK|ñLXðM|ñP rðQ|ñR wðS|ñZQð[|ñ^Xð_|ñb @ðc|ñd pðe|ðf 	ˆoÐÐ2Ð3Ø˜: yÐ2_ðaðg|ñjsðk|ñn zðo|ñpgðq|ñt_ðu|ñH[ðI|ñTaðU|ñX bðY|ñbJðc|ðh 	˜oÐ.Ð.EÐFØ�z =Ð2[ð]ði|ñlVðm|ñppðq|ñt wðu|ñvpðw|ñzoð{|ñ~ fð|ñ@ lðA|ñB^ðC|ñFiðG|ñLPðM|ñP oðQ|ñR gðS|ñT }ðU|ñV ~ðW|ñX zðY|ñdPðe|ñl sðm|ñn fðo|ñp vðq|ñr zðs|ñt gðu|ñx Bðy|ñz zð{|ðF 	!  ¨Ð.?Ð@ÐBSÐU_Ðaoð  r^ð  _ðG|ðH 	$ L >°/Ð1BÐCØ˜
 NÐ4`ðbðI|ðL 	!  ¨fÐ5Ð7IÈ:ÐWeð  hJð  KðM|ñPzðQ|ñT^ðU|ñX |ðY|ñZ lð[|ñ^Uð_|ñb eðc|ñd fðe|ñjAðk|ñ|Wð}|ñF	lðG	|ñL	bðM	|ñP	xðQ	|ñT	 hðU	|ñj	 Ð)Ó*Ø˜ ]ð  5PðQðk	|ñn	 Ð(Ó)Ø˜z¨=ð  ;YðZðo	|ñr	 Ð-Ó.Ø˜f mð  6SðTðs	|ñv	Dðw	|ñz	 Ð*Ó+Ø˜& -Ð1|ð~ð{	|ñ~	 Ð)Ó*Ø 
¨Mð  <JðKð	|ñB
MðC
|ñF
 Ð/Ó0Ø˜v }Ð6bðdðG
|ñJ
 Ð.Ó/Ø# Z°ð  AVðWðK
|ñN
WðO
|ñ^
lð_
|ñf
Xðg
|ñn
pðo
|ñr
 Gðs
|ñt
oðu
|ñ~
 Bð
|ñ@pðA|ñF AðG|ñH ðI|ñJfðK|ñNpðO|ñReðS|ñV`ðW|ñZgð[|ðl 	1°°¸}¸oð N:Ø:F¸ÈÀØ˜j˜\Ð)`ÐajÐ`kÐklÐmxÐlyÐyzð|ð �f˜nÐ.dðfðm|ñtUðu|€ñ| `oÔoÑ_nÈ^ÈW˜bŸj™j¨°"·-±-Ó@ÐHÀ4ÔHÑ_nÒoÐ ñ (ó )fó gÐ ð5�5˜#ð 5˜u cð 5¨7°Cð 5¸Àð 5ÀUÈCð 5ÐQUÐWZð 5Ð\aÐcfð 5ÐhoÐqtð 5Ø˜3ð5Ø '¨ð5Ø.5°sð5Ø<BÁJð5ØPVÑXbð5ØdiÐkoð5à˜$ð5à &©ð5€ð —Z’Zð[Ø\^×\iÑ\iókÐ ð
 —Z’ZðAàBDÇ-Á-óQÐ ð —*’*Ð8Ó9€õõ	!ð 9;¸DÀ#Ð 5€Ð!Ð#5óZÐ ó eÐ ã:Ð ðKØÐ ðKØ"*Ð,CðKØEMÐObðKàˆmðKà%Ð'8ðKà:BÐDYðKð ÐðKð !)Ð*IðKð ˆoð	Kð  (¨ð	Kð ;CÐDUð	Kð
 ˆnðKð
 '¨ðKð
 9AÀ-ðKð
 RZÐ[hðKð Ð$ðKð '/Ð0IðKÐ ñ Ð+Ó,€Ø/Ð1FÐGÐ õAõõðJ �jŠjÐGÓH€ð —J’JÐOÓPÐ õ÷.ð ñL ˜<Ð)>Ð?Ó@€õ÷Nð Nõ*õ$8òÐXZð Ø/3÷ð ÷>}ð }õ C÷*ð *ñ\ =Ð õ#ñL PÐ õiõX÷vùóO ps   Ë*R,