skill-miner — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited skill-miner (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Turn the signal buried in past coding-agent sessions into new and existing "Agent Skills". A session earns a skill only when it clears this gate — repeatable AND (room to do it better OR a repeated ask):
is the strongest evidence, but a plausibly-recurring task counts; a genuine one-off never does. (Required.)
first:
quirks of this environment, roundabout paths and their shortcuts, hard-won heuristics. These are literally skills.
to pick their brain (a correction, a better way they knew, a fact we got wrong).
they don't have to ask again.
Pipeline: discover → distill (cheap LLM, per conversation) → group, judge & generate.
A small LLM must be reachable. Check it first:
python3 scripts/llm.py --check # prints the backend it will use, or how to enable oneSet one of OPENAI_API_KEY / GEMINI_API_KEY / OPENROUTER_API_KEY, or have a claude / codex / gemini CLI on PATH. Override model with SKILL_MINER_MODEL, force a backend with SKILL_MINER_LLM.
Keep your working directory at the launch directory: all artifacts go under ./out there — Skill Studio reads run progress from it.
OUT=./out
python3 scripts/discover.py --since 35 --out $OUT/inventory.jsonl # find transcripts across agents
python3 scripts/extract.py --inventory $OUT/inventory.jsonl --out $OUT/conversations.jsonl --workers 10discover.py walks each adapter in common.py:ADAPTERS (Claude Code, Codex,opencode; add more there) and keeps sessions from the last --since days. Start with at most 100 conversations unless the user asks for more. Add --limit 15 to extract.py to sample fast.
extract.py parses each conversation and emits one JSONL row:agent, session_id, path, main_dir, datetime, n_user_turns, topics[], tasks[], skills_used[], env_feedback[], user_feedback[]. main_dir = the deepest folder where most work happened (from edited / read / mentioned files), not the launch cwd. topics are the scope (usually one — doubling as the headline — for grouping). tasks, env_feedback, and user_feedback are short arrays the cheap LLM copies from the user's own words (each [] for the typical session) — they map to the gate's three dimensions. The cheap call sees only user turns, so env_feedback is what the user said about what ran, not raw tool output — verify it in step 4.
Read conversations.jsonl — one row per session. At ≤100 rows the whole file fits in context, so read it. (If you mined many more, skim with jq/grep for rows with non-empty env_feedback / user_feedback first, then read the interesting slices.) Ignore rows whose topics is <error> or trivial/empty.
Cluster by task archetype — the KIND of work, not directory alone (e.g. "CI deploy debugging", "settings UI iteration", "dependency migration") — to judge dimension 1 (repeatable): which tasks recur or clearly could. Then, across the rows, gather the other two dimensions:
env_feedback and user_feedback that point at a way to do atask better next time (lead with environment feedback). A single hard-won lesson is a lead even without a cluster around it.
tasks (the userkeeps asking for the same thing).
Set aside one-off setup steps and lone offhand remarks. Keep short notes: named groups, each with its conversation count, dominant main_dir(s), the feedback / repeated asks it carries, and a few example paths to open as evidence next.
Read references/quality-bar.md and apply its gate: repeatable AND (feedback OR a repeated ask).
especially one whose feedback says it fell short; if a candidate overlaps it, open that SKILL.md and edit it in place. To find skill file paths:
python3 scripts/skills_inventory.pyUse it only to find files to edit; your context stays the source of truth for the landscape. If a candidate centers on a specific repo, check what Markdown docs already exist there (README.md, design docs, plans); if the recurring knowledge belongs in those docs instead of a skill, recommend that to the user in your report.
path field) to confirm the signal is real and to capture the specifics — the exact rule, the exact error and workaround, the better path the user pointed to, the repeated ask. Read the user's words around any correction and around [skill used: X] markers. The condensed rows show only user turns, so the transcript is where you verify what the environment actually did. Separate a recurring quirk (write it down) from one-time setup (a one-line gotcha at most).
has either room to do it better (feedback) or a repeated ask. The three dimensions carry equal weight — don't drop a hard-won lesson because the task appeared once if it clearly recurs, and don't ship a repeatable task that has nothing to improve and no repeated ask.
trigger, the steps/commands, the quirk + workaround — with file paths relative to the repo root (src/pages/Run.tsx), never machine-specific absolutes (/home/<user>/…) copied from a transcript. Where it lands:
fork or copy it. Skill Studio tracks every skill in git, so the user reviews your uncommitted changes (flagged on its home page) and either saves a version or reverts.
~/.agents/skills/generated-skills/<name>/. Skill Studio surfaces anything staged there as a Proposed skill the user can Accept (promote into ~/.agents/skills/) or Discard — so don't drop new skills straight into a live home.
came from. For each notable rejected candidate, say in one line which dimension it missed. Include any repo docs you think should be updated instead of, or in addition to, the skill changes.
Each agent stores transcripts differently. To support a new one (Gemini CLI, Cursor, …) add a (discover_fn, parse_fn) pair to common.py:ADAPTERS that yields the normalized record (_norm(...)). The rest of the pipeline is unchanged. Cursor (sqlite state.vscdb) is not yet wired up — opencode's adapter is a DB-backed (SQLite) template to follow.
--out artifacts and theskills you choose to generate or improve — new skills land staged under ~/.agents/skills/generated-skills/, edits go in place to the existing skill.
subagent`) are filtered out — only real user conversations are mined.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.