Read the project's transcripts for work that repeats, both the work the user asks for and the work you do to satisfy it, then propose a remedy for each pattern nothing already covers. Build nothing unless the user picks it.
Arguments: $ARGUMENTS
Read the transcripts of the project directory named in the arguments, or of the
current working directory if the arguments name none. If they ask for every
project (say, "all transcripts"), pass --all. If they name a focus area
instead (say, "testing" or "anything involving jj"), read the current project's
transcripts and keep only candidates in that area.
Load /distill first. It covers reducing a body of data to an artifact. This
skill supplies the data (transcripts), the question ("what work recurs?"), and
the artifact (a proposal list).
Workflow
- Run
extract-prompts.sh(in this skill's directory) with the project directory as its argument, or--allfor every project, writing its output to a file in the scratchpad directory. It prints one tab-separatedproject,session id,timestamp,promptline per prompt, sowc -lgives the prompt count andcut -f2 | sort -uthe session count. Pass--max-chars 900when the prompts are too long to read whole: it keeps each request and marks how much it cut. For a pasted log or a plan, that is all you need. Say in the report that you truncated. When the project has no transcripts it exits with an error. Report that and stop - Run
extract-actions.sh(in this skill's directory) with the same argument, writing its output to a second file in the scratchpad directory. It prints one line per tool call, from the main thread and from the subagents a session spawned, with each tool's input reduced to a signature. Never read this file whole. See "Reading the action extract" - Enumerate what already covers repetitive work here, before reading a single prompt, so you judge candidates against a fixed list. See "Enumerating existing coverage"
- Read every extracted prompt. Call none irrelevant before you read it
- Cluster the prompts by what the user wanted, not by the words used. "Rewrite this so each function stays at one level" and "this reads bottom-up, fix it" are one task. For each cluster, keep every prompt in it, the sessions it spans, and two or three verbatim examples showing the range. See "What counts as repetitive work"
- Cluster the actions. See "Reading the action extract"
- Judge each cluster against the enumeration. See "Judging existing coverage"
- For each surviving candidate, choose the remedy. See "Choosing a remedy", then "Choosing a level" for the remedies that have one
- Report as in "Reporting". Offer to build the ones the user picks: run
/create-skillfor a skill,/update-configfor a hook or a permission entry, and write a rule, script, or fix yourself
Enumerating existing coverage
List what already exists, with a one-line summary of each:
- User skills:
~/.claude/skills/*/SKILL.md - Project skills:
<project>/.claude/skills/*/SKILL.md - Project commands:
<project>/.claude/commands/*.md - Plugin and built-in skills: the ones listed in this session's available-skills list
- Rules:
~/.claude/CLAUDE.mdand everyCLAUDE.mdin the project - Hooks and permissions: the
hooksandpermissionskeys of~/.claude/settings.jsonand the project's.claude/settings.json - Scripts: the project's
package.jsonscripts,Makefiletargets, and whatever it keeps inscripts/orbin/
Count them by kind. The report opens with those counts. Read every summary, and the body of anything close to a candidate. A name is not a procedure. Only the body describes what it does.
What counts as repetitive work
A cluster is a candidate when all of these hold:
- It holds three or more prompts spanning two or more sessions. One elaborate request is not a pattern; three plain ones are. Prompts repeated inside a single session count as one, because they are one task restated
- The user wanted the same outcome each time, whatever the phrasing
- The next occurrence is likely. A migration that finished last month will not come up again
A cluster that meets the last two but holds two prompts, one per session, is borderline. Report it in a separate list of weaker candidates. Never drop it silently.
The counts are the argument. A proposal without prompts behind it is your taste, presented as evidence.
Corrections tell you more than plain requests do. A prompt that corrects what you did ("no, split that into separate commits first") states a procedure the user expects and you missed. Several such prompts across sessions form one candidate.
Other kinds of clusters worth keeping:
- A preference restated in different projects or files
- A sequence the user walks you through step by step, the same way each time
- A command invoked repeatedly with the same hard-to-remember flags
- A prompt that is nothing but context you could have looked up yourself: a file path, a command's flags, a convention already written down
- Requests that already invoke a skill and then correct its output: evidence to amend that skill, not to add one
These aren't exhaustive. Reason from first principles when none fits cleanly.
Reading the action extract
A prompt cluster shows what the user asked for more than once. An action cluster shows what the same request cost: the commands re-derived, the files re-read, the calls that failed before they worked.
extract-actions.sh prints one tab-separated line per tool call:
| Column | Contents |
|---|---|
| 1 | project |
| 2 | session id |
| 3 | timestamp |
| 4 | tool name |
| 5 | signature: Bash:jj diff, Edit:src/parse.py, Skill:humanize |
| 6 | err when the call returned an error, empty otherwise |
| 7 | the skill that was running, empty when there was none |
| 8 | the subagent id, empty on the main thread |
| 9 | the input, truncated to 120 characters, or 900 for a subagent prompt |
Calls made inside a subagent are included, under the session that spawned them, so session counts cover both. Column 8 separates them.
The extract runs to thousands of lines, so read counts before lines. Run the
queries below, read the top 30 rows of each, then read column 9 for the few
signatures that pass the threshold. The commands assume the extract is at $A.
Sessions spanned per signature. This is the primary table, because the threshold counts sessions:
cut -f2,5 "$A" | sort -u | cut -f2 | sort | uniq -c | sort -rn | head -30
Failures per signature. A command that errors in session after session indicates a broken default, a missing dependency, or a missing wrapper:
awk -F'\t' '$6 == "err"' "$A" | cut -f5 | sort | uniq -c | sort -rn | head -30
Files opened at the start of a session. A file read first in many sessions is
context to add to CLAUDE.md or to a document CLAUDE.md links:
awk -F'\t' '$4 == "Read" { if (++n[$2] <= 5) print $5 "\t" $2 }' "$A" |
sort -u | cut -f1 | sort | uniq -c | sort -rn | head -30
Recurring sequences. Three signatures in a row, with consecutive repeats collapsed, counted once per session. A sequence that recurs across sessions is a procedure worth writing down:
awk -F'\t' '{ if ($2 != s) { s = $2; a = ""; b = ""; p = "" }
if ($5 == p) next
p = $5
if (a != "" && b != "") print a " > " b " > " $5 "\t" $2
a = b; b = $5 }' "$A" |
sort -u | cut -f1 | sort | uniq -c | sort -rn | head -30
Failures per skill. A skill whose calls fail is a skill to amend, and column 7 contains it:
awk -F'\t' '$6 == "err" && $7 != ""' "$A" |
cut -f5,7 | sort | uniq -c | sort -rn | head -30
To read a cluster once counting has selected it, filter to its signature:
awk -F'\t' '$5 == "Bash:uv run pytest"' "$A" | cut -f2,6,7,9 | head -40
Thresholds match the prompt side: three or more occurrences spanning two or more sessions, with two occurrences borderline.
Subagent invocations are the exception to counting. A project produces tens of them, not thousands, and each prompt states a task in full, so column 9 keeps the prompt itself up to 900 characters. Read every one:
awk -F'\t' '$4 == "Agent"' "$A" | cut -f2,5,9
Cluster these the way you cluster the user's prompts, by what was asked. A prompt written to a subagent three times across sessions is a strong skill candidate, because you wrote the procedure out and threw it away each time. The prompt is a first draft of the skill, and its repetitions show which parts stayed fixed and which varied. The fixed parts become the skill's body and the varying parts its arguments.
Discard the patterns that dominate every table and indicate nothing on their own: search-then-substitute loops, and repeated Edits to one file. What counts is a signature tied to this project: its own scripts, its test commands, its files.
Where an action cluster restates a prompt cluster, merge it into that one as
evidence of the cost, and report it once. A cluster of failing uv run ruff
calls next to prompts asking to fix formatting is one candidate, not two.
An action cluster is weaker evidence than a prompt cluster, because the user chose the prompts and you chose the actions. A command run many times may be many tries at one badly specified job. Read column 7 before proposing anything, and say in the report which clusters rest on actions alone.
Judging existing coverage
For each candidate, one of three verdicts:
- Covered: something already covers this. Drop it, and name what covers it in the report so the user can see the judgment
- Adjacent: something covers work near it but not it. Name the boundary, and whether the fix is a new thing or an amendment to the existing one
- Uncovered: nothing covers it
A shared noun is not coverage. /review reading pull requests does not cover
writing an issue body. Compare procedures, not topics.
Choosing a remedy
Take the first that fits:
- Fix the cause. The work recurs because something is broken or missing: a flaky test, a bad default, an error message that contains no fix, a step the build should do itself. Automating around it is the wrong remedy. Propose the repair
- A rule in
CLAUDE.md, when the remedy is one line of standing guidance with no steps: a tool to prefer, a convention to keep - A script, when the steps are deterministic and need no judgment. Name where it lives and what invokes it
- A hook in
settings.json, when the work should happen every time some event occurs, without being asked. The harness runs hooks, but a rule cannot guarantee the work happens - A permission entry, when the repetition is approval prompts rather than
work.
/fewer-permission-promptsalready does this. Name it and move on - A skill, when the task takes an ordered procedure with judgment calls
worth writing down. Load
/create-skillfor the conventions - An agent definition in
.claude/agents/, when the repetition is a prompt written to a subagent: the same role, tools, and standing instructions each time, with only the target varying. The varying part becomes the prompt, and the rest becomes the definition
One cluster can warrant two remedies, such as a script plus the skill that specifies when to run it. Say so rather than picking one.
These aren't exhaustive. Reason from first principles when none fits cleanly.
Choosing a level
Skills, rules, hooks, and permission entries live at user level or project level. Scripts and fixes live in the project.
Project level when the work depends on something in this repository: its build commands, directory layout, deploy steps, schema, or its own conventions.
User level when the work depends only on the user's tools and taste, and would carry over unchanged to another repository. Transcripts from one project undercount a user-level pattern because the same work in other projects is not in this sample.
When both readings fit, propose user level with the project-specific parts passed as arguments, and say so.
Reporting
Open with the scope: which project or projects, how many prompts, how many tool calls, how many sessions, the date range, and how many existing skills, rules, hooks, and scripts you checked against.
Then the proposals from the prompts, most prompts first, each as:
- The work, in one imperative line, and its counts:
N prompts across M sessions - Two or three verbatim prompts, quoted and trimmed to their point
- Coverage: uncovered, or adjacent with what it neighbors and the boundary
- Remedy: which kind, or which existing thing to amend, and one line on what it would do
- Level: user or project, with the reason in a clause, or where the script or fix goes
Then, under a heading of its own, the proposals that rest on actions alone. The user never asked for these, so each one opens with the evidence:
- The signature or sequence, and its counts:
N calls across M sessions, plusK failedwhere any did - Two or three lines from column 9, quoted
- What the pattern indicates, in one line: the missing context, the missing wrapper, the step that failed
- Coverage, remedy, and level, as above
Then the borderline list, one line each. Close with:
- Candidates dropped as covered, one line each with what covers them
- Action clusters merged into a prompt proposal, one line each
- What the sample misses: prompts you could not classify, tool calls whose signature was too coarse to cluster, the prompts written to subagents, which the prompt extract excludes because the user did not write them, and other projects' transcripts you did not read