
K Skill Cleaner
Audit which local agent skills are actually used before you remove clutter from a skills repo or ~/.claude workspace.
Overview
K-skill-cleaner is an agent skill most often used in Operate (also Build agent-tooling) that scans local skill folders and agent logs to produce a conservative uninstall shortlist without deleting files.
Install
npx skills add https://github.com/nomadamas/k-skill --skill k-skill-cleanerWhat is this skill?
- Dependency-free Python helper scans root-level skill folders with conservative exclusions for .git, node_modules, and ag
- Best-effort usage signals from Claude Code, Codex, and OpenCode JSONL/log paths via skill-trigger and SKILL.md load mark
- Produces a cleanup shortlist only—never deletes files by itself
- Optional interview choices to tune how aggressive the shortlist is
- Documents three agent-specific log source patterns with stated confidence levels
- Scans three named agent families: Claude Code, Codex, and OpenCode
- Uses a fixed set of excluded root directories including .git, node_modules, and common agent config folders
Adoption & trust: 1.1k installs on skills.sh; 5.4k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have a growing pile of agent skills and no reliable picture of which ones your agents actually invoked in the last few weeks.
Who is it for?
Solo builders maintaining a monorepo or dotfiles tree with many third-party skills who want log-backed usage hints before manual cleanup.
Skip if: Teams that need centralized MDM policy, cloud-side skill registry analytics, or fully automated uninstall pipelines without human review.
When should I use this skill?
You maintain many local SKILL.md folders and want log-backed usage signals before manual removal.
What do I get? / Deliverables
You get a conservative, log-informed shortlist of skills to review or remove so your repo and agent context stay lean without accidental mass deletion.
- Conservative cleanup shortlist with skill names and evidence notes
- JSON or structured summary suitable for a human review ticket
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Skill hygiene is a recurring production concern once you ship with many skills installed; operate/iterate is the canonical shelf for trimming and reconciling what still earns disk and context. Iterate fits ongoing repo maintenance: shortlist stale skills after scanning folders and logs without auto-deleting anything.
Where it fits
Before adding ten new marketplace skills, run a shortlist pass so only high-signal packages stay in the repo.
Pre-release, confirm no experimental skills with zero log hits remain in paths your CI agents load.
Monthly iterate: reconcile folder inventory with Claude and Codex session markers to archive dead skills.
When onboarding a contractor, export which skills the team actually used so their install set matches reality.
How it compares
Use instead of deleting skill folders by gut feel or last-modified date when you want best-effort transcript correlation.
Common Questions / FAQ
Who is k-skill-cleaner for?
Indie and solo developers who install skills from skills.sh or git subfolders and need a repeatable audit before they prune their stack.
When should I use k-skill-cleaner?
During operate/iterate maintenance, before a large skills import, or when build/agent-tooling sessions feel slow because too many unused SKILL.md files load; it also helps after ship when you standardize which skills new teammates may install.
Is k-skill-cleaner safe to install?
The skill is designed not to delete files itself, but it reads filesystem paths and local logs—review the Security Audits panel on this page and confirm paths before acting on any shortlist.
SKILL.md
READMESKILL.md - K Skill Cleaner
#!/usr/bin/env python3 """Utilities for the k-skill-cleaner skill. The helper intentionally stays dependency-free: it scans root-level skill folders, best-effort local agent logs, and optional interview choices to produce a conservative cleanup shortlist. It never deletes files by itself. """ from __future__ import annotations import argparse import json import os import re from collections.abc import Iterable, Mapping from datetime import datetime, timedelta, timezone from pathlib import Path from typing import Any EXCLUDED_ROOT_DIRS = { ".changeset", ".claude", ".codex", ".cursor", ".git", ".github", ".omx", ".ouroboros", ".vscode", "docs", "examples", "node_modules", "packages", "python-packages", "scripts", } AGENT_USAGE_SOURCES = [ { "agent": "Claude Code", "paths": ["~/.claude/projects/**/*.jsonl", "~/.claude/transcripts/**/*.jsonl"], "method": "Scan JSONL transcript lines for skill-trigger events, $skill mentions, and SKILL.md load markers.", "confidence": "best-effort", }, { "agent": "Codex", "paths": ["~/.codex/sessions/**/*.jsonl", "~/.codex/log/**/*.log", ".omx/logs/**/*.log"], "method": "Scan Codex session/log lines for routed skill names, $skill invocations, and SKILL.md reads.", "confidence": "best-effort", }, { "agent": "OpenCode", "paths": ["~/.local/share/opencode/**/*.jsonl", "~/.config/opencode/**/*.jsonl"], "method": "Scan OpenCode data/config logs when available; ask for an exported transcript otherwise.", "confidence": "best-effort", }, { "agent": "OpenClaw/ClawHub", "paths": ["~/.openclaw/**/*.jsonl", "~/.clawhub/**/*.jsonl"], "method": "No stable public trigger-count schema is assumed; use local logs if present or imported JSON counts.", "confidence": "manual-confirm", "fallback": "Ask the user to export trigger stats or provide a usage JSON file.", }, { "agent": "Hermes Agent", "paths": ["~/.hermes/**/*.jsonl", "~/.config/hermes/**/*.jsonl"], "method": "No stable public trigger-count schema is assumed; use local logs if present or imported JSON counts.", "confidence": "manual-confirm", "fallback": "Ask the user to export trigger stats or provide a usage JSON file.", }, ] def resolve_skills_root(root: Path | str) -> Path: """Resolve the directory that contains installable skill directories. Standalone installs tell users to run this helper from inside the ``k-skill-cleaner`` directory with ``--skills-root .``. In that layout, the current directory is itself a skill, while sibling skill directories live in the parent directory. Treat that self-skill root as shorthand for its parent so the advertised standalone command scans the installed skill bundle. """ root_path = Path(root).expanduser().resolve() if (root_path / "SKILL.md").is_file(): parent = root_path.parent if any( child.is_dir() and child.name not in EXCLUDED_ROOT_DIRS and (child / "SKILL.md").is_file() for child in parent.iterdir() ): return parent return root_path def find_skill_dirs(root: Path | str) -> list[str]: """Return root-level directories that look like installable skills.""" root_path = resolve_skills_root(root) skills: list[str] = [] for child in root_path.iterdir(): if not child.is_dir() or child.name in EXCLUDED_ROOT_DIRS: continue if (child / "SKILL.md").is_file(): skills.append(child.name) return sorted(skills) def _walk_strings(value: Any, key_hint: str | None = None) -> Iterable[tuple[str | None, str]]: if isinstance(value, str): yield key_hint, value elif isinstance(value, Mapping): for key, child in value.items(): yield from