Ë
    ãß²jïž  ã                   ó
  — U 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 ddlm	Z	m
Z
mZ ddlmZmZmZmZmZ ddlmZ ddlmZmZ ddlmZ dd	lmZmZ dd
lmZm Z m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5 ddl6m7Z7  ejp                  e9«      Z:i Z;e<e=d<   dZ>de?fd„Z@ e«       ZAeAdz  ZBeBZCde	fd„ZDdaEdZFdeGdeeG   fd„ZHdeeGeGf   fd„ZIdid„ZJdeGfd„ZK eKd«      ZL eKd«      ZM eKd«      ZN eKd«      ZO eKd«      ZPdeQfd „ZRd!e	deeG   fd"„ZSdeeG   fd#„ZTdjdeGd$eGdeQfd%„ZUdeeVeVe	f   fd&„ZWd'd(œd)eQdeeeGef      fd*„ZXdeeeGef      deeeGef      fd+„ZYdkd,eGd-eGdeGfd.„ZZd/„ Z[d0e	deQfd1„Z\d0e	d2e	deQfd3„Z]d4„ Z^d5d6gd'd'fd7g d8¢d9d'fd:d;gd9d9fd<g d=¢d'd'ffZ_d>ee	   de<fd?„Z`d>e	d@e	fdA„ZadBeeGef   dCeGdee<e<f   fdD„ZbdEe	dee	   fdF„ZcdGe	de?fdH„ZddeQfdI„ZedeGdJeeG   dKeVfdL„ZfdeGdEe	dMeGfdN„Zg	 dldeGdOeGd-eGdPeQdeGf
dQ„ZhdRdSdTd,dUdVdWœig dXœdYœZidZd[dTdUd\dWœdUd]dWœd^œdgdXœdYœZj ejÖ                  dRdeid_„ eRd`¬a«       db„ Zl ejÖ                  dZdejeleRd`¬a«       ddclmmnZn dddlmoZo ddlpZpddlqZqdedfdgœZrdh„ Zsy)mus  Skills Tool â€” list and view skill documents (progressive disclosure). A skill is a directory
holding SKILL.md (YAML frontmatter + instructions) plus optional references/, templates/, assets/,
scripts/. `skills_list` returns name/description only; `skill_view` returns full content and
linked files. Sibling modules (skills_tool_setup / _plugin / _dedup) re-export here.é    N)Úsuppress)ÚPathÚPurePosixPathÚPureWindowsPath)ÚAnyÚDictÚListÚOptionalÚTuple)Úget_hermes_home)ÚregistryÚ
tool_error)Úcfg_get)ÚEXCLUDED_SKILL_DIRSÚis_skill_support_path)ÚSkillReadinessStatusÚ_build_setup_noteÚ'_capture_required_environment_variablesÚ#_get_required_environment_variablesÚ_is_env_var_persistedÚ_is_remote_env_backend)ÚMAX_DESCRIPTION_LENGTHÚMAX_NAME_LENGTHÚ_INJECTION_PATTERNSÚ_failÚ_jsonÚ_mark_background_review_readÚ_preprocess_skillÚ_read_skill_textÚ_safe_frontmatterÚ_serve_plugin_skillÚ_serve_skill_fileÚ_truncate_description)Ú_check_skill_view_dedupÚ_record_skill_viewÚreset_skill_view_dedup)Úis_background_reviewÚ_SKILLS_CACHEg      >@Úreturnc                 ón  — ddl m} t        t        |dd«      dd«      }g }| D ]Ç  }	 |j                  «       j                  }t        t
        «      5  t        j                  |«      5 }|D ]R  }t        t
        «      5  |j                  d¬«      r&t        ||j                  d¬«      j                  «      }ddd«       ŒT 	 ddd«       ddd«       |j                  t        |«      |f«       ŒÉ t        |«      t        |«      |fS # t
        $ r Y Œìw xY w# 1 sw Y   Œ³xY w# 1 sw Y   ŒaxY w# 1 sw Y   ŒexY w)	zƒO(#dirs + #categories) stat-based change signature; platform is read via
    ``agent.skill_utils.sys`` so test patches are honored.r   ©Úskill_utilsÚsysNÚplatformÚ F)Úfollow_symlinks)Úagentr,   ÚgetattrÚstatÚst_mtimeÚOSErrorr   ÚosÚscandirÚis_dirÚmaxÚappendÚstrÚtupleÚ	frozenset)	Údirs_to_scanÚdisabledÚ_skill_utilsr.   ÚsigÚdÚmÚitÚentrys	            ú6/home/ubuntu/.hermes/hermes-agent/tools/skills_tool.pyÚ_skills_scan_signaturerG   *   s5  € õ 2Ü”w˜|¨U°DÓ9¸:ÀrÓJ€HØ
€CØò 
 ˆð	Ø—‘“×!Ñ!ˆAô ”gÓñ 	O¤§
¡
¨1£ð 	O°Øò O�ÜœgÓ&ñ OØ—|‘|°E�|Ô:Ü  5§:¡:¸e :Ó#D×#MÑ#MÓN˜÷Oð OñO÷	O÷ 	Oð
 	�
‰
”C˜“F˜A�;Õð
 ô �#‹Jœ	 (Ó+¨XÐ6Ð6øô ò 	Ùð	ú÷Oð Oú÷	Oð 	Oú÷ 	Oð 	OúsM   §DÁD+Á&DÁ;9DÂ4
DÂ?D+Ä	DÄDÄDÄDÄD(Ä$D+Ä+D4	Úskillsc                  óP   — t        t        «      } | t        k7  r| S t        «       dz  S )z½Active profile's skills dir at call time: the patched ``SKILLS_DIR`` when a patcher changed
    it, else live profile-scoped HERMES_HOME (long-lived runtimes may import before profile set).rH   )r   Ú
SKILLS_DIRÚ_SKILLS_DIR_AT_IMPORTr   )Ú
configureds    rF   Ú_skills_dirrM   C   s*   € ô ”jÓ!€JØ#Ô'<Ò<ˆ:Ð^Ä/ÓBSÐV^ÑB^Ð^ó    z>Use a skill name or relative path within the skills directory.Únamec                 óæ   — ddl m} t        | t        «      syt	        | j                  «       x}«      }t        |«      j                  «       s|j                  «       s|j                  ry ||«      ryy)z¯Error if lookup *name* could escape the search roots it is joined onto. Windows drive
    paths are rejected too: their ``:`` would be misread as a plugin namespace separator.r   )Úhas_traversal_componentzSkill name must be a string.z?Skill name must be a relative path within the skills directory.z9Skill name cannot contain '..' path traversal components.N)	Útools.path_securityrQ   Ú
isinstancer;   r   Ústripr   Úis_absoluteÚdrive)rO   rQ   Ú	candidateÚwins       rF   Ú_skill_lookup_path_errorrY   N   sZ   € õ <Ü�dœCÔ Ø-Ü
 t§z¡z£|Ð3˜)Ó
4€CÜ�YÓ×+Ñ+Ô-°·±Ô1BÀcÇiÂiØPÙ˜yÔ)ØJØrN   c                  ó4   — ddl m}   | t        «       dz  «      S )z°Snapshot of HERMES_HOME/.env for the post-skill secret-capture diff (same tokenizer that
    installs the profile scope, so a captured value never differs from the served one).r   ©Úload_env_filez.env)Úagent.secret_scoper\   r   r[   s    rF   Úload_envr^   \   s   € õ 1áœÓ*¨VÑ3Ó4Ð4rN   c                 ó   — | a y ©N)Ú_secret_capture_callback)Úcallbacks    rF   Úset_secret_capture_callbackrc   d   s   € à'ÑrN   Úattrc                 ó.   ‡ — ˆ fd„}‰ x|_         |_        |S )zULazy call-time delegate to ``agent.skill_utils.<attr>`` (re-export; patches honored).c                  ó.   •— ddl m}  t        |‰«      | Ž S )Nr   r+   )r1   r,   r2   )Úargsr,   rd   s     €rF   Ú	_delegatez(_skill_utils_delegate.<locals>._delegatek   s   ø€ Ý%Ø)Œw�{ DÓ)¨4Ð0Ð0rN   )Ú__name__Ú__qualname__)rd   rh   s   ` rF   Ú_skill_utils_delegaterk   i   s    ø€ ô1ð 37Ð6€IÔ˜Ô/ØÐrN   Úskill_matches_platformÚskill_matches_environmentÚskill_matches_appsÚparse_frontmatterÚget_disabled_skill_namesc                   ó   — y)NT© rr   rN   rF   Úcheck_skills_requirementsrs   z   s   € ØrN   Ú
skill_pathc                 ód  — t        «       g}t        t        «      5  ddlm} |j                   |«       «       ddd«       |D ]T  }t        t        «      5  t        | j                  |«      j                  x}«      dk\  r|d   cddd«       c S 	 ddd«       ŒV y# 1 sw Y   ŒcxY w# 1 sw Y   ŒmxY w)z“``~/.hermes/skills/mlops/axolotl/SKILL.md`` -> ``"mlops"``; active profile dir first
    (respects test monkeypatching), then skills.external_dirs.r   )Úget_external_skills_dirsNé   )
rM   r   Ú	ExceptionÚagent.skill_utilsrv   ÚextendÚ
ValueErrorÚlenÚrelative_toÚparts)rt   Údirs_to_checkrv   Ú
skills_dirr~   s        rF   Ú_get_category_from_pathr�   ~   s®   € ô !“]�O€MÜ	”)Ó	ñ 9Ý>Ø×ÑÑ5Ó7Ô8÷9ð $ò  ˆ
Ü”jÓ!ñ 	 Ü˜J×2Ñ2°:Ó>×DÑDÐD�5ÓEÈÒJØ˜Q‘x÷	 ó 	 ØJ÷	 ð 	 ð ð ÷9ð 9ú÷	 ð 	 ús   ›BÁ.B&ÂB#Â&B/	c                 ó¬  — | sg S t        | t        «      r*| D �cg c]  }|sŒt        |«      j                  «       ‘Œ  c}S t        | «      j                  «       } | j	                  d«      r| j                  d«      r| dd } | j                  d«      D �cg c]2  }|j                  «       sŒ|j                  «       j                  d«      ‘Œ4 c}S c c}w c c}w )z:Tags from frontmatter: a parsed list, "[a, b]", or "a, b".ú[ú]é   éÿÿÿÿú,z"')rS   Úlistr;   rT   Ú
startswithÚendswithÚsplit)Ú
tags_valueÚts     rF   Ú_parse_tagsrŽ   Œ   s¨   € áØˆ	Ü�*œdÔ#Ø(2Ö8 1²a”�A“—‘•Ò8Ð8Ü�Z“×&Ñ&Ó(€JØ×Ñ˜SÔ! j×&9Ñ&9¸#Ô&>Ø  "Ð%ˆ
Ø,6×,<Ñ,<¸SÓ,AÖO qÀQÇWÁWÅYˆA�G‰G‹I�O‰O˜EÕ"ÒOÐOùò	 9ùò Ps   ™C¡CÂCÂ(!Cr.   c                 ód  — 	 ddl m}  |«       j                  di «      }|xs t        j                  d«      }|s*t        t        «      5  ddlm}  |d«      xs d}ddd«       d}|rt        |d	|«      }|duxr | |v }|xs | |j                  d
g «      v S # 1 sw Y   Œ<xY w# t        $ r Y yw xY w)zóDisabled in config? Platform precedence: explicit arg, ``HERMES_PLATFORM``, session
    ``HERMES_SESSION_PLATFORM``. A globally-disabled skill stays disabled on every platform
    (keep in sync with agent.skill_utils.get_disabled_skill_names).r   )Úload_configrH   ÚHERMES_PLATFORM)Úget_session_envÚHERMES_SESSION_PLATFORMr/   NÚplatform_disabledr?   F)
Úhermes_cli.configr�   Úgetr6   Úgetenvr   rx   Úgateway.session_contextr’   r   )rO   r.   r�   Ú
skills_cfgÚresolved_platformr’   r”   Úin_platforms           rF   Ú_is_skill_disabledrœ   ˜   sË   € ðÝ1Ù “]×&Ñ& x°Ó4ˆ
Ø$ÒD¬¯	©	Ð2CÓ(DÐÙ Üœ)Ó$ñ UÝCÙ$3Ð4MÓ$NÒ$TÐRTÐ!÷Uð !ÐÙÜ '¨
Ð4GÐIZÓ [ÐØ'¨tÐ3ÒQ¸Ð@QÐ8QˆØÒD˜d j§n¡n°ZÀÓ&DÐDÐD÷Uð Uûô ò Ùðús*   ‚AB# Á	BÁ:B# ÂB ÂB# Â#	B/Â.B/c                  ó”   — ddl m} m} t         |«       «      }t	        «       }||j                  «       r|gng z   }| | «       z  }|||fS )z�(project_dirs, all_dirs, active_skills_dir); trusted project-local dirs come FIRST so
    first-wins dedup / the collision resolver prefer them.r   )rv   Úget_project_skills_dirs)ry   rv   rž   rˆ   rM   Úexists)rv   rž   Úproject_dirsÚactive_skills_dirÚall_dirss        rF   Ú_skill_search_dirsr£   ­   sW   € ÷ TÜÑ/Ó1Ó2€LÜ#›ÐØÐ6G×6NÑ6NÔ6PÐ 1Ñ2ÐVXÑY€HØÑ(Ó*Ñ*€HØ˜Ð#4Ð4Ð4rN   F)Úskip_disabledr¤   c                 óþ  ‡— ddl m}mŠ | rdnd}| r
t        «       n	t	        «       }t        «       \  }}}t        ||«      }t        j                  «       }t        j                  |«      }	|	�3|	d   |k(  r+||	d   z
  t        k  r|	d   D �
cg c]  }
t        |
«      ‘Œ c}
S g }t        «       }|D �]A  }||v r|nˆfd„} ||«      D �]'  }t        d	„ |j                  D «       «      rŒ!	 t        t!        |«      dd
 «      \  }}t#        |«      rt%        |«      rt'        |«      sŒ^|j                  d|j(                  j*                  «      dt,         }||v s||v rŒ”|j                  dd«      }|sHt/        d„ t1        t2        j4                  |j5                  «       j7                  d«      «      D «       |«      }|j9                  |«       |j;                  |t=        |«      t?        |«      dœ«       �Œ* �ŒD |||ft        |<   |D �
cg c]  }
t        |
«      ‘Œ c}
S c c}
w # t@        tB        f$ r"}tD        jG                  d||«       Y d}~�Œ„d}~wtH        $ r$}tD        jG                  d||d¬«       Y d}~�Œ¯d}~ww xY wc c}
w )z³All skills (name, description, category) across project/local/external dirs, first-wins
    by name; cached per session. ``skip_disabled=True`` ignores disabled state (config UI).r   )Úiter_project_skill_filesÚiter_skill_index_filesÚwith_disabledÚfilteredNr…   é   c                 ó   •—  ‰| d«      S ©NúSKILL.mdrr   )rB   r§   s    €rF   ú<lambda>z"_find_all_skills.<locals>.<lambda>É   s   ø€ ÑTjÐklÐnxÓTy€ rN   c              3   ó,   K  — | ]  }|t         v –— Œ y ­wr`   )Ú_EXCLUDED_SKILL_DIRS)Ú.0Úparts     rF   ú	<genexpr>z#_find_all_skills.<locals>.<genexpr>Ë   s   è ø€ ÒK°D�4Ô/Ô/ÑKùs   ‚i   rO   Údescriptionr/   c              3   óF   K  — | ]  }|r|j                  d «      s|–— Œ y­w)ú#N)r‰   )r±   Úlns     rF   r³   z#_find_all_skills.<locals>.<genexpr>Ö   s'   è ø€ ò (J¨rÙ+-°b·m±mÀCÔ6Hô )+ñ (Jùs   ‚!Ú
)rO   r´   Úcategoryz Failed to read skill file %s: %sz)Skipping skill at %s: failed to parse: %sT©Úexc_info)%ry   r¦   r§   ÚsetÚ_get_disabled_skill_namesr£   rG   ÚtimeÚ	monotonicr(   r–   Ú_SKILLS_CACHE_TTL_SECONDSÚdictÚanyr~   Ú_parse_frontmatterr   rl   rm   rn   ÚparentrO   r   ÚnextÚmapr;   rT   r‹   Úaddr:   r#   r�   ÚUnicodeDecodeErrorÚPermissionErrorÚloggerÚdebugrx   )r¤   r¦   Ú	cache_keyr?   r    r>   Ú_Ú	signatureÚnowÚcachedÚsrH   Ú
seen_namesÚscan_dirÚ_iterÚskill_mdÚfrontmatterÚbodyrO   r´   Úer§   s                        @rF   Ú_find_all_skillsrÙ   ¸   sl  ø€ ÷ SÙ#0‘°j€IÙ%ŒsŒuÔ+DÓ+F€HÜ$6Ó$8Ñ!€L�, Ü& |°XÓ>€IÜ
�.‰.Ó
€CÜ×Ñ˜yÓ)€FØÐ˜f Q™i¨9Ò4¸#ÀÀqÁ	¹/ÔMfÒ9fð "(¨¡Ö+˜A”�Q•Ò+Ð+Ø€FÜ“e€JØ ó fˆØ,4¸Ñ,DÑ(ÓJyˆÙ˜h›ó 	fˆHÜÑK¸H¿N¹NÔKÔKØðfÜ$6Ô7GÈÓ7QÐRWÐSWÐ7XÓ$YÑ!�˜TÜ-¨kÔ:ÔB[Ð\gÔBhô  qCð  DOô  qPØØ"—‘ v¨x¯©×/CÑ/CÓDÐEUÄoÐV�Ø˜:Ñ%¨°Ñ)9ØØ)Ÿo™o¨m¸RÓ@�Ù"Ü"&ñ (J´S¼¿¹ÀDÇJÁJÃL×DVÑDVÐW[ÓD\Ó5]ô (JØKVó#X�Kà—‘˜tÔ$Ø—‘ tÔ<QÐR]Ó<^Ü+BÀ8Ó+LñNö Oò	fðfð2 !*¨3°Ð7„M�)ÑØ#Ö$˜ŒD��GÒ$Ð$ùò; ,øô, '¬Ð8ò NÜ—‘Ð?ÀÈ1×MÒMûÜò fÜ—‘ÐHÈ(ÐTUÐ`d�×eÒeûðfüò
 %s=   Â	HÃ%;HÄ!5HÅBHÈI:ÈI7È*IÉI7ÉI2É2I7c                 ó   — t        | d„ ¬«      S )z3Keep every skill listing path ordered the same way.c                 ó6   — | j                  d«      xs d| d   fS )Nr¹   r/   rO   ©r–   )rÑ   s    rF   r®   z_sort_skills.<locals>.<lambda>ç   s   € ¨¯©¨zÓ):Ò)@¸bÀ!ÀFÁ)Ð(L€ rN   ©Úkey)Úsorted)rH   s    rF   Ú_sort_skillsrà   å   s   € ä�&ÑLÔMÐMrN   r¹   Útask_idc                 ó  — 	 t        «       j                  dd¬«       t        «       }	 ddlm}m}  |«         |«       j                  «       D ]?  }|j                  di «      }t        |«      rt        |d   «      rŒ/|j                  |«       ŒA 	 |st        dg g d	d
œ«      S | r$|D �cg c]  }|j                  d«      | k(  sŒ|‘Œ }}t!        |«      }t#        |D �ch c]%  }|j                  d«      sŒ|j                  d«      ’Œ' c}«      }t        d||t%        |«      ddœ«      S # t        $ r t        j                  dd¬«       Y Œ¹w xY wc c}w c c}w # t        $ r }	t'        t)        |	«      d¬«      cY d}	~	S d}	~	ww xY w)zTTier 1 listing: name + description (+ category) only; ``task_id`` is handler parity.T)ÚparentsÚexist_okr   ©Údiscover_pluginsÚget_plugin_managerrÖ   rO   zPlugin skill listing failedrº   z%No skills found in skills/ directory.)ÚsuccessrH   Ú
categoriesÚmessager¹   z@Use skill_view(name) to see full content, tags, and linked files)rè   rH   ré   ÚcountÚhintF©rè   N)rM   ÚmkdirrÙ   Úhermes_cli.pluginsræ   rç   Úlist_plugin_skill_metadataÚpoprl   rœ   r:   rx   rÊ   rË   r   r–   rà   rß   r|   r   r;   )
r¹   rá   Ú
all_skillsræ   rç   Úplugin_skillrÖ   rÑ   ré   rØ   s
             rF   Úskills_listrô   ê   sy  € ð1Ü‹×Ñ D°4ÐÔ8Ü%Ó'ˆ
ð		GßOÙÔÙ 2Ó 4× OÑ OÓ Qò 0�Ø*×.Ñ.¨}¸bÓA�Ü-¨kÔ:Ô>PÐQ]Ð^dÑQeÔ>fØØ×!Ñ! ,Õ/ñ	0ñ Ü T°RÀrØ%LñNó Oð OáØ%/ÖQ °1·5±5¸Ó3DÈÓ3Pš!ÐQˆJÐQÜ! *Ó-ˆ
Ü¸
ÖX°1ÀaÇeÁeÈJÕFW˜QŸU™U :Õ.ÒXÓYˆ
ÜØ zÀÜ˜“_ØVñXó Yð 	Yøô ò 	GÜ�L‰LÐ6ÀˆLÖFð	Güò RùâXøô
 ò 1Üœ#˜a›&¨%Ô0Õ0ûð1úsk   ‚%E ¨A&D& ÂE Â!E Â'EÃEÃE ÃEÃ2EÄ E Ä& E	ÅE ÅE	Å	E Å	E?ÅE:Å4E?Å:E?c           
      ó<  — ddl m}m} ddlm}m}  || «      \  }}	 ||«      st        d|› d| › d�«      dfS  |«         |«       }
d}	 ddlm}m	}  |«       } ||«       |
j                  | «      }|€%||k(  r 	 dd
lm}  ||«       |
j                  | «      }|�5|j                  «       s%|
j!                  | «       t        d| › d|› d�«      dfS |�t#        |||	|||¬«      dfS |
j%                  |«      x}r:t        d|	› d|› d�|D �cg c]	  }|› d|› �‘Œ c}d|› dt'        |«      › d�¬«      dfS d|	r|› d|	› �fS dfS # t        $ r!}t        j                  d	|«       Y d}~�Œd}~ww xY w# t        $ r!}t        j                  d||«       Y d}~Œùd}~ww xY wc c}w )u  ``plugin:skill`` dispatch: ``(result_json, None)`` when answered, else ``(None,
    local_category_name)`` to fall through to the flat-tree scan â€” categorized local skills also use
    ``category:skill`` in config/gateway prompts, so the on-disk ``category/skill`` form returns.r   )Úis_valid_namespaceÚparse_qualified_namerå   zInvalid namespace 'z' in 'z('. Namespaces must match [a-zA-Z0-9_-]+.N)Ú_get_active_memory_providerÚ&_prune_inactive_memory_provider_skillsz2Failed pruning inactive memory-provider skills: %s)Úload_memory_providerz1Failed lazy memory-provider skill load for %s: %súSkill 'z' file no longer exists at uT   . The registry entry has been cleaned up â€” try again after the plugin is reloaded.)Ú	file_pathÚ
preprocessÚ
session_idz' not found in plugin 'z'.ú:zThe 'z' plugin provides z
 skill(s).©Úavailable_skillsrì   ú/)ry   rö   r÷   rï   ræ   rç   r   Úplugins.memoryrø   rù   rx   rÊ   rË   Úfind_plugin_skillrú   rŸ   Úremove_plugin_skillr!   Úlist_plugin_skillsr|   )rO   rü   rá   rý   rö   r÷   ræ   rç   Ú	namespaceÚbareÚpmÚactive_memory_providerrø   rù   ÚexcÚplugin_skill_mdrú   Ú	availablerÑ   s                      rF   Ú_resolve_plugin_skillr    s#  € ÷ KßGÙ*¨4Ó0�O€IˆtÙ˜iÔ(ÜÐ*¨9¨+°V¸D¸6ÐAiÐjÓkÐmqÐqÐqÙÔÙ	Ó	€BØ!ÐðPßfÙ!<Ó!>ÐÙ.Ð/EÔFð ×*Ñ*¨4Ó0€Oð Ð 9Ð0FÒ#Fð	^Ý;Ù  Ô+Ø ×2Ñ2°4Ó8ˆOð Ð"¨?×+AÑ+AÔ+CØ
×Ñ˜tÔ$ÜØ�d�VÐ6°Ð6Gð HNð OóPàQUðVð 	Vð Ð"Ü"Ø˜Y¨¸	ÈjÐelônØosðtð 	tà×)Ñ)¨)Ó4Ð4€yÐ4ÜØ�d�VÐ2°9°+¸RÐ@Ø:CÖD°Q  ¨1¨Q¨CÒ0ÒDØ˜˜Ð#5´c¸)³nÐ5EÀZÐPôRð TXðXð 	Xð ©4�Y�K˜q  Ð'Ð:Ð:°TÐ:Ð:øô3 ò PÜ�‰ÐIÈ3×OÒOûðPûô ò 	^Ü�L‰LÐLÈiÐY\×]Ñ]ûð	^üò Es6   Á	D? Á9E, ÄF
Ä?	E)ÅE$Å$E)Å,	FÅ5FÆFÚpathc                 ó˜   ‡— | Št        t        «      5  | j                  «       Šddd«       t        ˆfd„|D «       «      S # 1 sw Y   ŒxY w)zITrue when ``path`` (resolved where possible) lives under one of ``dirs``.Nc              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wr`   )Úis_relative_to)r±   rB   Úresolveds     €rF   r³   z_under_any.<locals>.<genexpr>9  s   øè ø€ Ò8¨aˆx×&Ñ& q×)Ñ8ùs   ƒ)r   rx   ÚresolverÂ   )r  Údirsr  s     @rF   Ú
_under_anyr  4  sA   ø€ à€HÜ	”)Ó	ñ "Ø—<‘<“>ˆ÷"äÓ8°4Ô8Ó8Ð8÷"ð "ús   “A Á A	Úsearch_rootc           	      ó¬   ‡‡— 	 | j                  ‰«      Št        ˆˆfd„t        dt	        ‰j
                  «      «      D «       «      S # t        $ r Y yw xY w)zMTrue when a legacy Markdown candidate belongs to an ancestor directory skill.Fc              3   óx   •K  — | ]1  } ‰j                   ‰j                  d | Ž dz  j                  «       –— Œ3 y ­wr¬   )Újoinpathr~   Úis_file)r±   ÚdepthÚrelativer  s     €€rF   r³   z-_is_package_owned_markdown.<locals>.<genexpr>B  s?   øè ø€ ò àð 
ˆ×	Ñ	˜xŸ~™~¨f¨uÐ5Ð	6¸Ñ	C×LÑL×Nñùs   ƒ7:r…   )r}   r{   rÂ   Úranger|   r~   )r  r  r  s    `@rF   Ú_is_package_owned_markdownr  <  sX   ù€ ðØ×#Ñ# KÓ0ˆô ô ä˜1œc (§.¡.Ó1Ó2ôó ð øô ò Ùðús   „A Á	AÁAc                 ó"  ‡	‡
‡— ddl m} g Š
t        «       Šdt        t           dt        ddfˆ
ˆfd„Š	dt        d	t        ddfˆ	fd
„}|D ]Ä  }t        d| |f«      D ]  } |||z  |«       Œ  ||d«      D ]L  }|j                  j                  | k(  st        |«      j                  d«      | k(  sŒ: ‰	|j                  |«       ŒN |j                  | › d�«      D ]4  }|j                  dk7  sŒt        |«      rŒt        ||«      rŒ, ‰	d|«       Œ6 ŒÆ ‰
S )aJ  ALL (skill_dir, skill_md) candidates across every dir and lookup strategy (direct path,
    recursive by dir / frontmatter name, legacy flat <name>.md), deduped by resolved path.
    Collision detection is the point: silent shadowing of a local skill by a same-named
    external one is a real bug class, so the caller refuses >1.r   )r§   ÚsdÚsmdr)   Nc                 óÄ   •— |}t        t        «      5  |j                  «       }d d d «       |‰vr%‰j                  |«       ‰j	                  | |f«       y y # 1 sw Y   Œ3xY wr`   )r   rx   r  rÇ   r:   )r!  r"  rÞ   Ú
candidatesÚseen_mds      €€rF   Ú_recordz*_collect_skill_candidates.<locals>._recordQ  s[   ø€ ØˆÜ”iÓ ñ 	 Ø—+‘+“-ˆC÷	 à�gÑØ�K‰K˜ÔØ×Ñ˜r 3˜iÕ(ð ÷	 ð 	 ús   “AÁAÚdirect_pathr  c                 ó  •— | j                  d«      }t        | «      s0| j                  «       r | dz  j                  «       r ‰| | dz  «       y |j                  «       r#t        |«      st	        ||«      s
 ‰d |«       y y y y )Nú.mdr­   )Úwith_suffixÚ_is_skill_support_pathr8   rŸ   r  )r'  r  Úflatr&  s      €rF   Ú_record_directz1_collect_skill_candidates.<locals>._record_directY  sz   ø€ Ø×&Ñ& uÓ-ˆÜ% kÔ2°{×7IÑ7IÔ7KÐQ\Ð_iÑQi×PqÑPqÔPsÙ�K ¨zÑ!9Õ:Ø�k‰kŒmÔ$:¸4Ô$@Ü0°°{ÔCÙ�D˜$Õð Dð %AˆmrN   r­   rO   r)  )ry   r§   r¼   r
   r   ÚfilterrÄ   rO   r    r–   Úrglobr+  r  )rO   Úlocal_category_namer¢   r§   r-  Ú
search_dirÚdirectÚfound_skill_mdÚfound_mdr&  r$  r%  s            @@@rF   Ú_collect_skill_candidatesr5  H  s.  ú€ õ
 9Ø46€JÜ“5€Gð)”HœT‘Nð )¬ð )°$ö )ð ¤Dð  ´tð  Àõ  ð ò (ˆ
Ü˜T DÐ*=Ð#>Ó?ò 	<ˆFÙ˜:¨Ñ.°
Õ;ð	<ñ 5°ZÀÓLò 	?ˆNØ×%Ñ%×*Ñ*¨dÒ2Ü(¨Ó8×<Ñ<¸VÓDÈÓLÙ˜×-Ñ-¨~Õ>ð	?ð #×(Ñ(¨D¨6°¨Ó6ò 	(ˆHØ—‘ Ó+Ô4JÈ8Õ4TÜ6°xÀÕLÙ˜˜hÕ'ñ	(ð(ð ÐrN   Ú
referencesú*.mdÚ	templates)r7  ú*.pyz*.yamlz*.ymlz*.jsonz*.texú*.shTÚassetsÚ*Úscripts)r9  r:  z*.bashz*.jsz*.tsz*.rbÚ	skill_dirc                 óB  — i }| rt         ndD ]‰  \  }}}}| |z  }|D ��cg c]h  }|j                  «       sŒ|r|j                  |«      n|j                  |«      D ].  }|r|j	                  «       rt        |j                  | «      «      ‘Œ0 Œj }	}}|	sŒ…|	||<   Œ‹ |S c c}}w )zPreferences/templates/assets/scripts of a directory skill (empty groups dropped).rr   )Ú_LINKED_FILE_SPECSrŸ   r/  Úglobr  r;   r}   )
r>  ÚfilesÚsubÚglobsÚ	recursiveÚ
files_onlyÚbaseÚgÚfÚfounds
             rF   Ú_skill_linked_filesrK  {  s­   € à€EÙCLÕ-?ÐRTò Ñ)ˆˆU�I˜zØ˜3‰ˆà38÷.Ø./¸D¿K¹K½MÙ'0�d—j‘j ”m°d·i±iÀ³lò.àÙ §¡¤ô �—‘˜iÓ(Õ)ð.Ø)ð.ˆñ .ò ØˆE�#ŠJðð €Lùó.s   ŸBµABr¡   c                 ó   — ddl m}m}m}  || |«      sy || |«      }i }|rUt	        t
        «      5  |dz  |z  |z  }t        j                  t        |«      «      }t        |t        «      r|ni }ddd«       t        |j                  d«      xs |j                  d«      xs d«      }	t        |j                  d	«      xs d«      }
d
|› d�|	rd|	› d�ndz   |
rd|
› �ndz   dz   }||	xs d|
xs ddœ|fS # 1 sw Y   Œ†xY w)zº(org_provenance dict, header text) for an org-mirror skill, else (None, ""). Announced IN
    the content the model consumes; the author is token-verified at push time by the sync plane.r   )ÚORG_PROVENANCE_FILEÚis_org_mirror_pathÚorg_id_of_path©Nr/   Ú_orgNÚauthor_deviceÚauthor_user_idr/   Útsu\   > [!NOTE] ORG-SHARED SKILL â€” provenance
> This skill is shared by your organisation (org `ú`z, last updated by `z, as of uP  ). It was reviewed and approved for the whole
> team â€” treat it as third-party instructions rather than your own notes.
> You MAY improve it in place like any other skill. Your edits are kept locally
> and are never overwritten by org updates; share them back with
> `hermes sync propose` (or automatically, if your org enables it).

)Úorg_idÚ	shared_byÚas_of)ry   rM  rN  rO  r   rx   ÚjsonÚloadsr   rS   rÁ   r;   r–   )r>  r¡   rM  rN  rO  Úprov_orgÚprovÚ	prov_pathÚloadedÚauthorrT  Úheaders               rF   Ú_org_provenance_headerra  ‰  s.  € ÷ ZÑYÙ˜iÐ):Ô;ØÙ˜iÐ):Ó;€HØ€DÙÜ”iÓ ñ 	>Ø)¨FÑ2°XÑ=Ð@SÑSˆIÜ—Z‘ZÔ 0°Ó ;Ó<ˆFÜ'¨´Ô5‘6¸2ˆD÷	>ô �—‘˜/Ó*ÒN¨d¯h©hÐ7GÓ.HÒNÈBÓO€FÜ	ˆT�X‰X�d‹^Ò!˜rÓ	"€Bð	=Ø=E¸JÀað	Iá.4Ð   ¨Ñ*¸"ñ	>ñ !ˆX�b�T‰? bñ	*ðRñ		Rð ð ¨Vª^°tÀbÂjÈDÑQÐSYÐYÐY÷!	>ð 	>ús   ±>C4Ã4C=rÖ   Ú
skill_namec           	      ó  — t        | «      }ddlm} t         |dd«      «      j	                  «       j                  «       xs d}t        «       }|D �cg c]$  }|j                  d«      st        |d   |«      s|‘Œ& }}t        ||«      }|r
t        «       }t        |d   «      }	|D �cg c]/  }|j                  d«      rŒ|d   |	v st        |d   |«      s|d   ‘Œ1 }
}t        |
«      }|D �cg c]  }|d   |
vsŒ|d   ‘Œ c}x}r	 ddlm}  ||«       | j                  dg «      }g }t#        |t$        «      r |r	 ddlm}  ||«      }|xs t        |«      }|rt*        j,                  nt*        j.                  }|g |
|g ||d   |j0                  dœ}i }t3        d„ |D «       d«      x}r||d<   |d   r|d   |d<   |
D �cg c]  }d|› �‘Œ	 c}|D �cg c]  }d|› �‘Œ	 c}z   }|r5t5        |||«      x}r&t7        |«      r|› d|j9                  «       › d�}||d<   ||fS c c}w c c}w c c}w # t        $ r t        j!                  d	|d
¬«       Y �Œ<w xY w# t        $ r t        j!                  d|d
¬«       Y �Œ w xY wc c}w c c}w )u  Resolve required env vars / credential files (prompting for secrets where the surface
    allows) and register what's available for sandboxes. Returns ``(fields, extras)``: fields go
    before ``_source_path`` in the skill_view result, extras after â€” key order is tool output.r   )Úterminal_envÚTERMINAL_ENVÚlocalÚoptionalrO   Úmissing_names)Úregister_env_passthroughz/Could not register env passthrough for skill %sTrº   Úrequired_credential_files)Úregister_credential_filesz0Could not register credential files for skill %sÚsetup_skipped)Úrequired_environment_variablesÚrequired_commandsÚ&missing_required_environment_variablesÚmissing_credential_filesÚmissing_required_commandsÚsetup_neededrl  Úreadiness_statusc              3   óJ   K  — | ]  }|j                  d «      sŒ|d    –— Œ y­w)ÚhelpNrÜ   )r±   rØ   s     rF   r³   z#_skill_readiness.<locals>.<genexpr>Ò  s   è ø€ ÒQ¨À1Ç5Á5ÈÅ=˜1˜V�9ÑQùs   ‚#™
#NÚ
setup_helpÚgateway_setup_hintzenv $zfile Ú zW-backed skills need these requirements available inside the remote environment as well.Ú
setup_note)r   Útools.terminal_scoperd  r;   rT   Úlowerr^   r–   r   r   r¼   ÚboolÚtools.env_passthroughri  rx   rÊ   rË   rS   rˆ   Útools.credential_filesrk  r   ÚSETUP_NEEDEDÚ	AVAILABLEÚvaluerÅ   r   r   Úupper)rÖ   rb  Úrequired_env_varsrd  ÚbackendÚenv_snapshotrØ   Úmissing_required_env_varsÚcapture_resultÚstill_missingÚ	remainingrr  Úavailable_env_namesri  Úrequired_cred_files_rawÚmissing_cred_filesrk  ÚstatusÚfieldsÚextrasrv  ÚnÚpÚmissing_itemsry  s                            rF   Ú_skill_readinessr“  ¥  sì  € ô <¸KÓHÐÝ1Ü‘,˜~¨wÓ7Ó8×>Ñ>Ó@×FÑFÓHÒSÈG€GÜ“:€Là$ö!YØØ�u‰u�ZÔ Ô)>¸qÀ¹yÈ,Ô)Wò 	
ð!YÐð !Yô =¸ZÐIbÓc€NÙ Ü“zˆÜ˜ Ñ7Ó8€Mà,ö`Ø°A·E±E¸*Õ4EØˆv‰Y˜-Ñ'Ô/DÀQÀvÁYÐP\Ô/]ð 	
ˆ&‹	ð`€Ið `ô ˜	“?€Là2CÖb¨QÀqÈÁyÐXaÒGa˜q ›yÒbÐbÐÐbð	gÝFÙ$Ð%8Ô9ð
 *Ÿo™oÐ.IÈ2ÓNÐØ!ÐÜÐ)¬4Ô0Ñ5Lð	hÝHÙ!:Ð;RÓ!SÐØ'ÒC¬4Ð0BÓ+CˆLñ 3?Ô!×.Ò.ÔDX×DbÑDb€Fà*;ÐRTØ2;Ø$6ÐUWØ$°~ÀoÑ7VØ"ŸL™Lñ*€Fð €FÜÑQÐ.?ÔQÐSWÓXÐX€zÐXØ)ˆˆ|ÑØÐ*Ò+Ø'5Ð6JÑ'KˆÐ#Ñ$Ø*3Ö4 Q�u˜Q˜C’[Ò4ÐM_Ö7`È¸%À¸sºÒ7`Ñ`€MÙÔ'8¸ÀÐPZÓ'[Ð[˜Ð[Ü! 'Ô*Ø&˜< q¨¯©«Ð(9ð  :Qð  RˆJØ)ˆˆ|ÑØ�6ˆ>Ðùò]!Yùò`ùò
 cøô ò 	gÜ�L‰LÐJÈJÐaeˆL×fð	gûô ò 	hÜ�L‰LÐKÈZÐbfˆL×gð	hüò 5ùÒ7`sN   Á)HÂ'H"Â>H"Ã,H'Ã9H'ÄH, Ä;I Æ?I<ÇJÈ,!IÉIÉ!I9É8I9rÕ   c                 ó~   — |D �cg c]  }| j                  |«      sŒt        |«      ‘Œ! }}t        |d„ d¬«      S c c}w )z£Most specific search dir containing *skill_md*, compared lexically: a symlinked entry
    belongs to the root that exposes it, not to the root its target lives in.c                 ó,   — t        | j                  «      S r`   )r|   r~   )rB   s    rF   r®   z$_owning_search_dir.<locals>.<lambda>â  s   € ¤S¨¯©£\€ rN   N)rÞ   Údefault)r  r   r9   )rÕ   r¢   rB   Úownerss       rF   Ú_owning_search_dirr˜  Þ  s>   € ð  (ÖF˜!¨8×+BÑ+BÀ1Õ+EŒd�1�gÐF€FÐFÜˆvÑ1¸4Ô@Ð@ùò Gs   …:œ:Úrootc                 ór   — | \  }}|j                   dk7  t        |j                  |«      j                  «      fS )zNReal SKILL.md beats a legacy flat ``<name>.md``, then the shallower path wins.r­   )rO   r|   r}   r~   )rW   r™  Ú
_skill_dirrÕ   s       rF   Ú_rank_same_root_candidaterœ  å  s6   € à$Ñ€J�Ø�M‰M˜ZÑ'¬¨X×-AÑ-AÀ$Ó-G×-MÑ-MÓ)NÐOÐOrN   c           
      óX  — 	 t        | D ��ch c]$  \  }}t        j                  j                  |«      ’Œ& c}}«      dk(  ryt        | D ��ch c]6  \  }}t	        j
                  |j                  «       «      j                  «       ’Œ8 c}}«      dk(  S c c}}w c c}}w # t        $ r Y yw xY w)a  True only when every candidate is the SAME skill: one resolved SKILL.md (symlink view)
    or byte-identical content (copy). Anything else is two different skills sharing a name,
    and picking one by depth would let ``<root>/evil`` (``name: github``) shadow the real one.r…   TF)	r|   r6   r  ÚrealpathÚhashlibÚsha256Ú
read_bytesÚ	hexdigestr5   )r$  Ú_sdr"  s      rF   Ú_provably_same_skillr¤  ë  sŠ   € ðÜ°j×A©(¨#¨s”—‘× Ñ  Õ%ÓAÓBÀaÒGØÜÐQ[×\ÁXÀSÈ#”G—N‘N 3§>¡>Ó#3Ó4×>Ñ>Õ@Ó\Ó]ÐabÑbÐbùó Bùã\øÜò Ùðús3   ‚
B Œ)B
µB Á
B Á;B
Â
B ÂB Â	B)Â(B)r0  r    c                 óˆ  ‡— |st        d«      ddfS t        | ||«      }t        |«      dkD  r&|r$|D �cg c]  }t        |d   |«      sŒ|‘Œ c}xs |}t        |«      dkD  rÁ|D ��ch c]  \  }}t	        ||«      ’Œ }}}t        |«      dk(  r•d|vr‘t        |«      r†|j                  «       Št        |ˆfd„¬«      }	t        |	d   ‰«      t        |	d   ‰«      k7  rGt        j                  d| t        |«      |	d   d   dj                  d	„ |	dd D «       «      «       |	d   g}t        |«      dkD  rn|D �
�cg c]  \  }
}t        |«      ‘Œ }}
}t        j                  d
| t        |«      dj                  |«      «       t        d| › dt        |«      › d�|d¬«      ddfS |r|d   nd\  }}|�0|r.ddlm} t        ||«      r ||«      rt        d| › d�d¬«      ddfS |r|j!                  «       s;t#        t%        «       «      dd D �cg c]  }|d   ‘Œ	 }}t        d| › d�|d¬«      ddfS d||fS c c}w c c}}w c c}}
w c c}w )zÐUnique on-disk skill for *name*: collision refusal, project-tier precedence, same-root
    precedence, quarantine gate, not-found listing. ``(error_json, skill_dir, skill_md)``;
    skill_md set iff no error.zISkills directory does not exist yet. It will be created on first install.Nr…   c                 ó   •— t        | ‰«      S r`   )rœ  )Úcr™  s    €rF   r®   z_locate_skill.<locals>.<lambda>  s   ø€ Ô6OÐPQÐSWÓ6X€ rN   rÝ   r   zJSkill '%s': %d identical same-root copies, resolved to %s (duplicates: %s)ú; c              3   ó8   K  — | ]  \  }}t        |«      –— Œ y ­wr`   )r;   )r±   r£  r"  s      rF   r³   z _locate_skill.<locals>.<genexpr>  s   è ø€ Ò%J±8°3¸¤c¨#§hÑ%Jùs   ‚u3   Skill name collision for '%s': %d candidates â€” %szAmbiguous skill name 'ú': u€    skills match across your local skills dir and external_dirs. Refusing to guess â€” load one explicitly by its categorized path.z‘Pass the full relative path instead of the bare name (e.g., 'category/skill-name'), or rename one of the colliding skills so each name is unique.)Úmatchesrì   ©NN)Úis_quarantined_project_skillzProject skill 'z“' is quarantined: the security scan flagged its content as dangerous. It will not load until the repo's skill content changes and passes a re-scan.zYInspect the skill in the repo checkout, or untrust the repo with `hermes skills untrust`.©rì   é   rO   rû   z' not found.z+Use skills_list to see all available skillsr   )r   r5  r|   r  r˜  r¤  rñ   rß   rœ  rÊ   ÚinfoÚjoinr;   Úwarningry   r­  rŸ   rà   rÙ   )rO   r0  r    r¢   r$  r§  r£  r"  ÚrootsÚrankedrÍ   Úpathsr>  rÕ   r­  rÑ   r  r™  s                    @rF   Ú_locate_skillr¶  ÷  s±  ø€ ñ ÜØWóYØZ^Ð`dðeð 	eä*¨4Ð1DÀhÓO€JÜ
ˆ:ƒ˜Ò™|ð ",ÖN˜A¬z¸!¸A¹$ÀÕ/M’aÒNÒ\ÐR\ˆ
Ü
ˆ:ƒ˜Òð
 DN×N±x°s¸CÔ# C¨Õ2ÐNˆÑNÜˆu‹:˜Š?˜t¨5Ñ0Ô5IÈ*Ô5UØ—9‘9“;ˆDÜ˜JÓ,XÔYˆFÜ(¨°©°DÓ9Ô=VÐW]Ð^_ÑW`ÐbfÓ=gÒgÜ—‘ÐhØ ¤# j£/°6¸!±9¸Q±<Ø ŸI™IÑ%J¸vÀaÀb¸zÔ%JÓJôLð % Q™i˜[�
Ü
ˆ:ƒ˜ÒØ(2×3™f˜a ”�S•Ð3ˆÑ3Ü�‰ÐLÈdÔTWÐXbÓTcÐei×enÑenÐotÓeuÔvÜØ$ T F¨#¬c°*«oÐ->ð ?dð dàðLô	Mð
 OSÐTXðYð 	Yñ ,6˜* Qš-¸<Ñ€Iˆxð Ð¡ÝBÜ�h Ô-Ñ2NÈxÔ2XÜØ! $ ð (kð kð+ô,ð .2°4ð	8ð 8ñ
 ˜8Ÿ?™?Ô,Ü(4Ô5EÓ5GÓ(HÈÈ"Ð(MÖN 1�Q�v“YÐNˆ	ÐNÜ�w˜t˜f LÐ1ÀIØGôIØJNÐPTðUð 	Uà�˜HÐ$Ð$ùòO Oùó Oùó 4ùò( Os   ³H.ÁH.Á&H3Ä5H9ÈH?Úcontentc                 óˆ  ‡— |j                  «       g}t        t        «      5  |j                  d„ |D «       «       ddd«       g }t	        ||«      s|j                  d|› �«       t        ˆfd„t        D «       «      r|j                  d«       |r't        j                  d| dj                  |«      «       yy# 1 sw Y   Œ~xY w)ak  Warn (never block) when loaded from outside the trusted dirs (project + local + external)
    and/or when common prompt-injection patterns appear. The check is on the RESOLVED path:
    every candidate is built as ``<search_dir>/...`` so a lexical test can never fire, and a
    SKILL.md symlinked to a file outside every root is exactly what this guards against.c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wr`   )r  )r±   rB   s     rF   r³   z)_log_security_warnings.<locals>.<genexpr>3  s   è ø€ Ò:¨A˜AŸI™IŸKÑ:ùs   ‚NzHskill file is outside the trusted skills directory (~/.hermes/skills/): c              3   óB   •K  — | ]  }|‰j                  «       v –— Œ y ­wr`   )r{  )r±   r‘  r·  s     €rF   r³   z)_log_security_warnings.<locals>.<genexpr>7  s   øè ø€ Ò
= Aˆ1�—‘“ÔÑ
=ùs   ƒzBskill content contains patterns that may indicate prompt injectionz#Skill security warning for '%s': %sr¨  )r  r   rx   rz   r  r:   rÂ   r   rÊ   r²  r±  )rO   rÕ   r·  r¢   r¡   Útrusted_dirsÚwarningss     `    rF   Ú_log_security_warningsr½  ,  sª   ø€ ð
 &×-Ñ-Ó/Ð0€LÜ	”)Ó	ñ ;Ø×ÑÑ:°Ô:Ô:÷;à€HÜ�h Ô-Ø�‰ÐbÐckÐblÐmÔnÜ
Ó
=Ô)<Ô
=Ô=Ø�‰Ð\Ô]ÙÜ�‰Ð<¸dÀDÇIÁIÈhÓDWÕXð ÷;ð ;ús   ¢B8Â8Crü   rý   c                 óÐ  ‡‡— 	 t        | «      x}rt        |t        ¬«      S d}d| v rt        | |||«      \  }}|�|S |rt        |«      x}rt        |t        ¬«      S t	        «       \  }}}	t        | |||«      \  }
}}|
�|
S 	 t        |«      }t        | ||||	«       t        |¬«      Št        ‰«      s)t        d| › d�t        j                  j                  ¬	«      S ‰j                  d
|j                  j                   «      }t#        |«      rt        d|› d�«      S |r|rt%        ||| ddd¬«      S ‰j                  d«      }t'        |t(        «      r|j                  di «      xs i ni Šˆˆfd„dD «       \  }}t+        |«      }	 t-        |j/                  |	«      «      }‰j                  d
|s|j2                  n|j                   «      }t5        ‰|«      \  }}|s|nt7        |||d|«      }d\  }}|r	 t9        ||	«      \  }}d|‰j                  dd«      ||||z   ||rt-        |«      nd||r|nd|rdnddœ|¥dt-        |«      i¥|¥}t?        |«       ‰j                  d«      r‰d   |d<   t'        |t(        «      r||d<   tA        |«      S # t        $ r}t        d| › d|› �«      cY d}~S d}~ww xY w# t0        $ rT |j                  j                  r.t-        |j/                  |j                  j                  «      «      n|j                   }Y �Œqw xY w# t        $ r t:        j=                  d|d¬«       Y �Œ6w xY w# t        $ r }tC        t-        |«      d¬«      cY d}~S d}~ww xY w)aK  View a skill (SKILL.md) or a file within its directory, as JSON. ``name`` is a skill name
    or path ("axolotl", "03-fine-tuning/axolotl"); "plugin:skill" resolves plugin-provided
    skills. ``preprocess`` applies the configured SKILL.md template / inline shell rendering;
    slash/preload callers render the message themselves.r®  Nrÿ   zFailed to read skill 'rª  )r·  rû   z$' is not supported on this platform.)rs  rO   zT' is disabled. Enable it with `hermes skills` or inspect the files directly on disk.Tz.Use a relative path within the skill directory)Úlist_availableÚ	mark_readrì   ÚmetadataÚhermesc              3   óz   •K  — | ]2  }t        ‰j                  |«      xs ‰j                  |d «      «      –— Œ4 y­w)r/   N)rŽ   r–   )r±   ÚkrÖ   Úhermes_metas     €€rF   r³   zskill_view.<locals>.<genexpr>h  s6   øè ø€ ò  kØJKŒK˜Ÿ™¨Ó*ÒD¨k¯o©o¸aÀÓ.D×Eñ kùs   ƒ8;)ÚtagsÚrelated_skillsz)Could not preprocess skill content for %srP  z'Could not resolve org provenance for %srº   r´   r/   zzTo view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml')rè   rO   r´   rÆ  rÇ  r·  r  r>  Úorg_provenanceÚlinked_filesÚ
usage_hintÚ_source_pathÚcompatibilityFrí   )"rY   r   Ú_LOOKUP_HINTr  r£   r¶  r   rx   r½  r    rl   r   ÚUNSUPPORTEDr�  r–   rÄ   rO   rœ   r"   rS   rÁ   rK  r;   r}   r{   Ústemr“  r   ra  rÊ   rË   r   r   r   )rO   rü   rá   rý   Úlookup_errorr0  Úservedr    r¢   r¡   Úerrorr>  rÕ   r·  rØ   Úresolved_namerÁ  rÆ  rÇ  rÉ  Úrel_pathrb  Ú	readinessÚreadiness_extrasÚrendered_contentrÈ  r`  ÚresultrÖ   rÅ  s                               @@rF   Ú
skill_viewrÙ  =  sá  ù€ ðH1ô 4°DÓ9Ð9ˆ<Ð9Ü˜¬LÔ9Ð9Ø*.ÐØ�$‰;Ü*?ÀÀiÐQXÐZdÓ*eÑ'ˆFÐ'ØÐ!Ø�ñ Ô4LÐM`Ó4aÐ$a LÐ$aÜ˜¬LÔ9Ð9Ü4FÓ4HÑ1ˆ�hÐ 1Ü%2ØÐ% |°Xó&?Ñ"ˆˆy˜(àÐØˆLð	@Ü& xÓ0ˆGô 	˜t X¨w¸ÐBSÔTÜ'°Ô8ˆÜ% kÔ2Ü˜7 4 &Ð(LÐMÔ`t÷  aAñ  aA÷  aGñ  aGô  Hð  HØ#Ÿ™¨°·±×0DÑ0DÓEˆÜ˜mÔ,Ü˜7 = /ð  2Fð  Gó  Hð  HÙ™Ü$Ø˜9 d¸4È4ØEôGð Gð —?‘? :Ó.ˆÜ<FÀxÔQUÔ<V�x—|‘| H¨bÓ1Ò7±RÐ\^ˆô kØOiô kÑˆˆnä*¨9Ó5ˆð	vÜ˜8×/Ñ/Ð0AÓBÓCˆHð !—_‘_ VÁ)¨X¯]ª]ÐQZ×Q_ÑQ_Ó`ˆ
Ü&6°{ÀJÓ&OÑ#ˆ	Ð#Ù*4™7Ô:KØ�Y Ð)TÐV`ó;bÐà!)Ñˆ˜ÙðcÜ)?À	ÐK\Ó)]Ñ&� ð  ZÀÇÁÐP]Ð_aÓ@bØ¨NÀvÐP`ÑG`Ø¹Y¬3¨y¬>ÈDØ,Ù,8™L¸dñ [gñ  Wð  mqñ
 ð ð
 ð œC ›Mñ
 ð ð
 ˆô 	% XÔ.Ø�?‰?˜?Ô+Ø&1°/Ñ&BˆF�?Ñ#Ü�h¤Ô%Ø!)ˆF�:ÑÜ�V‹}Ðøôc ò 	@ÜÐ1°$°°s¸1¸#Ð>Ó?Õ?ûð	@ûô* ò 	vØLTÏOÉO×LbÒLb”s˜8×/Ñ/°·±×0FÑ0FÓGÔHÐhp×huÑhu‹Hð	vûô ò cÜ—‘ÐFÈ
Ð]a�×bðcûô& ò 1Üœ#˜a›&¨%Ô0Õ0ûð1ús¼   „L< ¢L< ½L< Á#L< ÂJ ÂAL< Ã?L< ÄL< Ä1AL< ÆJ4 ÆAL< Ç3L ÈB
L< Ê	J1ÊJ,Ê&J1Ê'L< Ê,J1Ê1L< Ê4ALÌL< ÌLÌL< Ì!L9Ì5L< Ì8L9Ì9L< Ì<	M%ÍM ÍM%Í M%rô   zVList available skills (name + description). Use skill_view(name) to load full content.ÚobjectÚstringz*Optional category filter to narrow results)Útyper´   )rÜ  Ú
propertiesÚrequired)rO   r´   Ú
parametersrÙ  ah  Skills allow for loading information about specific tasks and workflows, as well as scripts and templates. Load a skill's full content or access its linked files (references, templates, scripts). First call returns SKILL.md content plus a 'linked_files' dict showing available references/templates/scripts. To access those, call again with file_path parameter.zŸThe skill name (use skills_list to see available skills). For plugin-provided skills, use the qualified form 'plugin:skill' (e.g. 'superpowers:writing-plans').z¤OPTIONAL: Path to a linked file within the skill (e.g., 'references/api.md', 'templates/config.yaml', 'scripts/validate.py'). Omit to get the main SKILL.md content.)rO   rü   c                 óX   — t        | j                  d«      |j                  d«      ¬«      S )Nr¹   rá   )r¹   rá   )rô   r–   )rg   Úkws     rF   r®   r®   ²  s#   € œ{°D·H±H¸ZÓ4HÐRT×RXÑRXÐYbÓRcÔd€ rN   u   ðŸ“š)rO   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚemojic                 ó–  — | j                  dd«      }|j                  d«      }t        «       rdn|}t        ||| j                  d«      «      x}�|S t        || j                  d«      |¬«      }t	        t
        «      5  t        j                  |«      }t        |t        «      r�|j                  d«      rt        ||| j                  d«      |«       |j                  d«      xs |x}rKdd	lm}	m}
  |
t        |«      «        |	t        |«      |j                  d«      |j                  d
«      ¬«       ddd«       |S # 1 sw Y   |S xY w)züInvoke skill_view, then bump view_count/use on success (best-effort). Repeat-view dedup
    mirrors read_file's unchanged-stub: a SAME, unchanged skill file already loaded in this
    session returns a short stub (cache cleared on context compression).rO   r/   rá   Nrü   )rü   rá   rè   r   )Úbump_useÚ	bump_viewrþ   )rá   rþ   )r–   r'   r$   rÙ  r   rx   rY  rZ  rS   rÁ   r%   Útools.skill_usagerè  ré  r;   )rg   rá  rO   rá   Údedup_task_idÚstubrØ  Úparsedr  rè  ré  s              rF   Ú_skill_view_with_bumprî  ¶  s  € ð �8‰8�F˜BÓ€DØ�f‰f�YÓ€Gô
 1Ô2‘D¸€MÜ'¨°t¸T¿X¹XÀkÓ=RÓSÐSˆÐ`ØˆÜ˜¨¯©°Ó(=ÀwÔO€FÜ	”)Ó	ñ 	dÜ—‘˜FÓ#ˆÜ�fœdÔ#¨¯
©
°9Ô(=Ü˜}¨d°D·H±H¸[Ó4IÈ6ÔRØ!Ÿ:™: fÓ-Ò5°Ð5ˆxÐ5ßAÙœ#˜h›-Ô(ñ œ˜X›°·±°yÓ0AÈbÏfÉfÐUaÓNbÕc÷	dð €M÷	dð €Mús   Á>B6D>Ä>E)ÚEnum)ÚSet)Úhermes_constantsÚdisplay_hermes_home)ÚutilsÚenv_var_enabled)rò  rô  c                 óÌ   — t         j                  | «      }|€t        dt        ›d| ›�«      ‚dd l}ddlm}  |t        | g|¢­Ž  t        |j                  |d   «      |d   «      S )Nzmodule z has no attribute r   )Ú	warn_oncer…   )	Ú_PLUGIN_COMPAT_LAZYr–   ÚAttributeErrorri   Ú	importlibÚhermes_cli.plugin_compatrö  r2   Úimport_module)rO   Útargetrù  rö  s       rF   Ú__getattr__rý  æ  se   € Ü ×$Ñ$ TÓ*€FØ€~Ü˜w¤x lÐ2DÀTÀHÐMÓNÐNÛÝ2ÙŒh˜Ð&˜vÓ&Ü�9×*Ñ*¨6°!©9Ó5°v¸a±yÓAÐArN   )r)   Nr`   r¬  )NNT)tÚ__doc__rŸ  rY  Úloggingr6   r¾   Ú
contextlibr   Úpathlibr   r   r   Útypingr   r   r	   r
   r   rñ  r   Útools.registryr   r   r•   r   ry   r   r°   r   r+  Útools.skills_tool_setupr   r   r   r   r   r   Útools.skills_tool_pluginr   r   r   r   r   r   r   r   r    r!   r"   r#   Útools.skills_tool_dedupr$   r%   r&   Útools.skill_provenancer'   Ú	getLoggerri   rÊ   r(   rÁ   Ú__annotations__rÀ   r<   rG   ÚHERMES_HOMErJ   rK   rM   ra   rÍ  r;   rY   r^   rc   rk   rl   rm   rn   rÃ   r½   r|  rs   r�   rŽ   rœ   rˆ   r£   rÙ   rà   rô   r  r  r  r5  r@  rK  ra  r“  r˜  rœ  r¤  r¶  r½  rÙ  ÚSKILLS_LIST_SCHEMAÚSKILL_VIEW_SCHEMAÚregisterrî  Úenumrï  rð  ÚreÚ	threadingr÷  rý  rr   rN   rF   ú<module>r     s’  ðòXó
 Û Û Û 	Û Ý ß 8Ñ 8ß 3Õ 3å ,ß /Ý %÷b÷X÷ X÷C÷ C÷ Có C÷Iñ Iå 7à	ˆ×	Ñ	˜8Ó	$€ð €ˆtÓ Ø Ð ð7°eó 7ñ( Ó€Ø˜8Ñ#€
Ø"Ð ð_�Tó _ð  Ð ØO€ð 3ð ¨8°C©=ó ð5�$�s˜C�x‘.ó 5ó(ð
 ó ñ /Ð/GÓHÐ á1Ð2MÓNÐ Ù*Ð+?Ó@Ð Ù*Ð+>Ó?Ð Ù1Ð2LÓMÐ ð 4ó ð¨ð °¸#±ó ð	P˜t C™yó 	Pñ˜Sð ¨Cð ¸4ó ð*5˜E $¨¨dÐ"2Ñ3ó 5ð /4ò *% tð *%¸¸TÀ#ÀsÀ(¹^Ñ8Ló *%ðZN˜˜d 3¨ 8™nÑ-ð N°$°t¸CÀ¸H±~Ñ2Fó Nñ
1˜#ð 1¨sð 1¸có 1ò<);ðX9�Tð 9 Dó 9ð	 Tð 	¸ð 	Àó 	ò(ðZ �F�8˜U EÐ*ØÒPÐRVÐX]Ð^Ø�ˆu�d˜DÐ!ØÒBÀEÈ5ÐQð	SÐ ð 8¨D¡>ð °dó ðZ dð Z¸tó Zð86 $ s¨C x¡.ð 6¸cð 6ÀeÈDÐRVÈJÑFWó 6ðrA ð A°H¸T±Nó AðP¨tð P¸ó Pð	¨ó 	ð2%˜ð 2%°(¸3±-ð 2%Ètó 2%ðjY ð Y°ð Y¸só Yð$ OSñN1Ø
ðN1ØðN1Ø/2ðN1ØGKðN1ØWZóN1ðd ØkààØ ØKñð
ð ñ	ñÐ ð  ð ~àð !ð  Añð
 !ð  Fññ	
ð �HññÐ ð& €× Ñ Ø	 Ð1CÙdØ&¨fõ6òð6 €× Ñ Ø	˜xÐ0AÐK`Ø&¨fõ6õ Ý Û 	Û ð GØ3ñÐ óBrN   