diff --git a/agent/skill_commands.py b/agent/skill_commands.py index e878326afeeed..ad1f03824d3fe 100644 --- a/agent/skill_commands.py +++ b/agent/skill_commands.py @@ -393,6 +393,14 @@ def build_skill_invocation_message( return f"[Failed to load skill: {skill_info['name']}]" loaded_skill, skill_dir, skill_name = loaded + + # Track active usage for Curator lifecycle management (#17782) + try: + from tools.skill_usage import bump_use + bump_use(skill_name) + except Exception: + pass # Non-critical — skill invocation proceeds regardless + activation_note = ( f'[IMPORTANT: The user has invoked the "{skill_name}" skill, indicating they want ' "you to follow its instructions. The full skill content is loaded below.]" @@ -432,6 +440,14 @@ def build_preloaded_skills_prompt( continue loaded_skill, skill_dir, skill_name = loaded + + # Track active usage for Curator lifecycle management (#17782) + try: + from tools.skill_usage import bump_use + bump_use(skill_name) + except Exception: + pass # Non-critical + activation_note = ( f'[IMPORTANT: The user launched this CLI session with the "{skill_name}" skill ' "preloaded. Treat its instructions as active guidance for the duration of this " diff --git a/tools/skills_tool.py b/tools/skills_tool.py index ed7a3e6a8d553..37319a74084fc 100644 --- a/tools/skills_tool.py +++ b/tools/skills_tool.py @@ -1497,8 +1497,12 @@ def _skill_view_with_bump(args, **kw): # qualified forms ("plugin:skill") return with the canonical name. resolved = parsed.get("name") or name if resolved: - from tools.skill_usage import bump_view + from tools.skill_usage import bump_use, bump_view bump_view(str(resolved)) + # A skill_view tool call is the agent actively loading the skill + # to act on it — that counts as use, not just a browse/view. + # Curator's stale timer keys off last_used_at (see agent/curator.py). + bump_use(str(resolved)) except Exception: pass return result