Plugin Watcher avatar

Plugin Watcher

Pricing

Pay per usage

Go to Apify Store
Plugin Watcher

Plugin Watcher

Analyzes Claude Code session transcripts to find the workflow patterns you repeat, then suggests and scaffolds the skills, agents, commands, and hooks worth building.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Jordaaan Hill

Jordaaan Hill

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

12 days ago

Last modified

Share

Find the workflows you keep repeating in Claude Code — and turn them into plugins.

Plugin Watcher reads your Claude Code session transcripts, detects tool-call sequences you run over and over, and tells you which ones are worth capturing as a skill, agent, slash command, hook, CLI tool, or config preset. It then writes the scaffold files for you.

No LLM calls. No conversation content leaves your machine in the output — only structural patterns.


Why use it

You've probably noticed you do the same dance a lot: read a config, edit it, npm run build, ssh to the box, restart the service. That five-step loop is a plugin waiting to happen — you just never notice it while you're in it.

Plugin Watcher notices it for you. It answers three questions:

  1. What am I actually repeating? — n-gram analysis over your real tool-call history.
  2. Is it worth automating? — a weighted score across frequency, consistency, complexity, and recency.
  3. What shape should it take? — a mapped plugin type plus a ready-to-drop-in scaffold file.

How it works

Session JSONL
┌─────────┐ ┌────────────┐ ┌──────────┐ ┌───────────┐ ┌────────────┐
│ Parser │──▶│ Classifier │──▶│ N-grams │──▶│ Scorer │──▶│ Suggester │
└─────────┘ └────────────┘ └──────────┘ └───────────┘ └────────────┘
extract label calls find repeat rank by map to a
tool calls semantically sequences value plugin type
Dataset + Markdown
report + scaffolds

Sessions are stored in a named key-value store (plugin-watcher-sessions) that persists across runs, so patterns compound the more sessions you feed it. Sessions are deduplicated by ID — re-ingesting the same session is a no-op.

Semantic classification

Raw tool names are too coarse. Bash → Bash → Bash tells you nothing. So every tool call is also labelled by what it actually does, using deterministic regex matching on the tool's input:

LabelMeans
Bash:sshssh / scp / rsync
Bash:gitgit / gh
Bash:testvitest, jest, pytest, mocha, npm test
Bash:buildnpm run build, tsc, make, cargo build
Bash:npmnpm / npx / pnpm / yarn / bun
Bash:apify · Bash:docker · Bash:curlApify CLI · Docker · HTTP requests
Bash:system · Bash:env · Bash:data · Bash:shellfilesystem · cd/export · jq · everything else
Read:config · Edit:source · Write:docsfile operations, classified by file type

File categories: config, source, docs, script, test, lock, glob, notebook, other.

That turns an opaque Bash → Bash → Edit into a legible Bash:git → Bash:build → Edit:config — which is a pattern you can actually name.


Input

Every field is optional. Running with no input at all analyzes everything already stored.

FieldTypeDefaultDescription
sessionJsonlstringRaw JSONL content of a Claude Code session transcript.
sessionIdstringautoSession UUID. Extracted from the JSONL if omitted.
analyzeSessionIdstringAnalyze only this one stored session instead of all of them.
analysisModeenumfullingest · analyze · full · schedule

Modes

  • ingest — parse and store a session. No analysis. This is what the stop hook uses on every session end.
  • analyze — run pattern detection across all stored sessions. No new input needed.
  • full (default) — ingest, then analyze.
  • schedule — incremental. Only runs if new sessions arrived since the last analysis, then updates the watermark. Use this for scheduled runs so you don't burn compute on unchanged data.

Example input:

{
"sessionJsonl": "{\"type\":\"assistant\",\"uuid\":\"...\"}\n{...}",
"sessionId": "3f2a91c4-8b7e-4d1a-9c33-6e5f0a2b7d81",
"analysisMode": "ingest"
}

Output

Dataset — one item per suggestion

{
"name": "remote-deploy",
"pluginType": "skill",
"score": 78.4,
"description": "Automate the Git → build → SSH remote workflow pattern.",
"rationale": "Detected 14 times across 6 session(s). Complex 4-step workflow that would benefit from automation. High frequency pattern — significant time savings potential.",
"trigger": "/remote-deploy",
"patternKey": "Bash:git→Bash:build→Bash:ssh→Bash:ssh",
"patternOccurrences": 14,
"patternSessions": 6,
"sessionIds": ["3f2a91c4-...", "8d0b7e21-..."],
"scores": { "frequency": 100, "complexitySavings": 80, "feasibility": 70 }
}

A pre-configured Plugin Suggestions table view surfaces name, type, score, description, and rationale.

Key-value store (plugin-watcher-sessions)

KeyContent
reportMarkdown report — summary metrics, sessions analyzed, top semantic patterns, top 10 recommendations with score breakdowns, full suggestion list.
scaffoldsMarkdown bundle of ready-to-use plugin files, each with its target path.
session-<uuid>A stored parsed session.
session-indexIndex of all stored session IDs.
last-analysis-timeWatermark for schedule mode.

Plugin types and where scaffolds land

TypeScaffold pathChosen when
skill.claude/skills/<name>/SKILL.mdSSH-heavy or long (4+ step) patterns
command.claude/commands/<name>.mdshort git workflows, 3 steps or fewer
agent.claude/agents/<name>.mdread + write combinations (code transformation)
hook.claude/hooks/<name>.shpatterns that start and end with a shell command
cli-toolnpx <name>shell-dominated mixed patterns
config.claude/settings.json snippetall-shell environment/setup patterns

Scoring

Two scores, applied in sequence.

1. Pattern score — is this sequence real, or noise?

ComponentWeightMeasures
Frequency40%occurrences relative to session count
Consistency30%how many distinct sessions it spans (a pattern in one session is a fluke)
Complexity20%sequence length, capped at 5
Recency10%100 within 7 days, 50 within 30, 10 beyond

2. Suggestion score — is this worth building?

ComponentWeightMeasures
Frequency40%inherited from the pattern
Complexity savings35%how many steps get collapsed
Feasibility25%how easy the plugin type is to build

Feasibility by type: command 90 · config 85 · hook 80 · skill 70 · cli-tool 60 · agent 50. A dead-simple slash command beats a speculative agent at equal frequency — the tool is biased toward things you'll actually ship.

Defaults: sequences of 2–5 tool calls, top 50 patterns scored, top 20 suggestions returned.


Automate it

Capture every session with a stop hook

Add to ~/.claude/settings.json (global) or .claude/settings.json (per-project):

{
"hooks": {
"stop": [
{ "command": "/path/to/plugin-watcher/hooks/stop.sh" }
]
}
}

The hook reads the transcript path from stdin, ships the JSONL to this Actor in ingest mode, and backgrounds the call so Claude Code never blocks on it. Requires jq and an authenticated apify CLI.

Then analyze on a schedule

In the Apify Console → Schedules, with input {"analysisMode": "schedule"}:

  • Daily — 0 9 * * *
  • Weekly — 0 9 * * 1

Ingest continuously, analyze periodically. That's the intended shape.

Call it directly

# CLI
apify call organized_ai/plugin-watcher --input='{"analysisMode":"analyze"}'
# API
curl -X POST "https://api.apify.com/v2/acts/organized_ai~plugin-watcher/runs?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"analysisMode":"analyze"}'

Privacy

This Actor is built to analyze structure, not content:

  • No prompts, no responses, no code appear in the dataset, report, or scaffolds — only tool names, semantic labels, sequences, counts, and timestamps.
  • Paths are sanitized/Users/<you>, /home/<you>, and C:\Users\<you> are collapsed to ~.
  • No third-party calls. Classification is regex-based and runs entirely inside the Actor. Nothing is sent to an LLM.

Note that ingested session transcripts are stored in your own Apify key-value store so patterns can accumulate across runs. They live in your account and are visible only to you.


Limitations

  • Detects sequences of 2–5 consecutive tool calls. Longer workflows show up as overlapping fragments rather than one unit.
  • Pattern quality scales with volume. One session gives you noise; twenty give you signal.
  • Generated names come from a category-combination table, so they're descriptive rather than clever — rename them.
  • Scaffolds are starting points, not finished plugins. They capture the shape of the workflow; you supply the logic.

Local development

npm install
npm run build # tsc
npm test # vitest
apify run # run locally
apify push # deploy

Node.js 22+. Built with the Apify SDK v3 and TypeScript.