A local detector for AI-writing patterns. Scores every prose file your agent saves. Python standard library only, no network, no model.
# Add to your Claude Code skills
git clone https://github.com/seyedehsanhadi/sloptrimLast scanned: 8/15/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-08-15T04:30:07.389Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}See how sloptrim compares with popular alternatives.
sloptrim is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by seyedehsanhadi. A local detector for AI-writing patterns. Scores every prose file your agent saves. Python standard library only, no network, no model. It has 210 GitHub stars.
Yes. sloptrim passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/seyedehsanhadi/sloptrim" and add it to your Claude Code skills directory (see the Installation section above). sloptrim ships a SKILL.md manifest, so compatible agents can discover and load it automatically.
sloptrim is primarily written in Python. It is open-source under seyedehsanhadi on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh sloptrim against similar tools.
No comments yet. Be the first to share your thoughts!
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
Trims AI slop from text. Works a catalogue of 71 patterns: 62 machine-checked by scripts/detect.py, 9 requiring semantic judgment during the rewrite. Of the 62, 50 can move the score; the rest are reported as writing advice and count for nothing. Mode-aware so it does not invent voice on factual content. Preserves facts. Rebuilds the cleaned text toward a selectable human-voice style profile so it does not read as a sterile de-AI'd husk.
This skill never talks about itself. It hands back the cleaned text and nothing else.
Never emit: any announcement that sloptrim ran, style/mode lines, scores or reports, drafts, self-audit notes, facts-preserved lines, change lists, preambles, closing offers.
Emit only:
Every internal step still runs - detector, tiering, self-audit, character scrub. Silence means nothing is printed, not that anything is skipped.
Break silence only for: (a) a fact you cannot preserve, or an unusual word you cannot verify against the domain - one line, then the text; (b) the user explicitly asking for the score, the report, a style choice, or a diff - then answer in full; (c) a high-stakes first-person deliverable - a cover letter, personal statement, or bio the user is about to send - where after the text you may add exactly one line offering a voice switch (for example: "Voice here is plain-professional; say the word for warmer or more formal."). One line, only for these high-stakes cases, never for routine prose.
Never ask. Read the content and pick:
If the user names a style or pastes a writing sample, that wins (see Matching the user's own voice).
scripts/detect.py and tier the pass to _metrics.ai_tell_score: clean (≤20) - character scrub and flagged spans only, do NOT rewrite (a human-first draft keeps its voice); light tells (21-40) - targeted edits plus rhythm repair; mixed and above - full rewrite toward the style profile.references/patterns.md when you need the precise Before/After examples for any pattern.python "$DETECT" on the draft; ask what still reads as AI, and whether it over-flattened (length_cv < 0.35, uniform paragraphs, readability_uniform true, contractions gone in drastic mode - a flat husk reads as machine-made just as fast as slop). Fix only the offending spans; cap at two loops; accept at clean/light tells and not over-flattened. Check the other direction in the same pass: count the words. Past 1.25x the input you have written new material, and no score justifies keeping it.python "$DETECT" on the final text and confirm invisible_chars, nonstandard_spaces, and homoglyphs are 0 (#62/#66/#67/#68 silent). Drafts from other models can carry zero-width or TAG-block characters that survive copy-paste; python "$DETECT" --clean strips them, normalizes spaces, folds homoglyphs, and trims stray whitespace without touching visible content.Removing AI tells is only half the job. The other half is rebuilding the text toward a voice a person would actually write in. Pick one from the content, silently (see Style, chosen silently). Each profile is a positive target - it does not change which AI tells are removed or the preservation rules; it sets the rhythm, register, punctuation, and paragraph shape the cleaned prose is rebuilt into.
1. 2000s textbook (default) - pre-LLM human academic prose (a well-edited textbook, roughly 2000-2008). Clear declarative sentences, one idea each; real length variation (a short statement, a longer development, a worked example - never metronomic); concrete examples introduced naturally; occasional first-person-plural for exposition, never first-person-singular opinion; semicolons and parentheses where a writer would use them, em-dash sparing. Forbidden: hype adjectives, signposting, hedge stacks, rule-of-three, "In today's world" openers, upbeat conclusions, emoji, bold-for-emphasis. Neutral and patient; explains, does not sell. Conservative mode.
2. Plain / clear (Zinsser) - tight modern nonfiction. Short words over long, cut every clutter phrase, concrete nouns and active verbs, one thought per sentence. Good for docs, READMEs, business prose. Conservative unless source is first-person.
3. Conversational essay - first-person, contractions, asides, real rhythm; reacts to facts rather than only reporting them; lets some mess in (tangents, half-formed thoughts). Implies drastic mode. Only for content that already carries a personal voice - never forced onto encyclopedic text.
4. Journalistic / news - AP style: short lede carrying the key fact first, inverted pyramid, attributed claims ("according to…"), plain verbs, no editorializing. Conservative.
If the user names a profile, rewrite toward it. Otherwise infer it per Style, chosen silently.
When the user provides a writing sample (inline or a file path), take the target voice from it instead of a profile: measure its sentence lengths and their variation, formality, paragraph openers, punctuation habits, recurring phrases - then rebuild the cleaned text with those habits. No sample: fall back to Content type and voice below.
The biggest failure mode is injecting authorial voice into content that has none by design. A Wikipedia article does not get to say "I keep coming back to..." Classify first:
Encyclopedic / factual - third-person, dense with proper nouns, dates, statistics, citations, technical vocabulary (Wikipedia, science, news, docs, specs). → Conservative mode. Remove AI patterns, vary rhythm, keep tone neutral. Do not add first-person stance, opinions, or asides. Keep formal contractions (it is, do not) as-is.
Opinion / first-person - already uses "I" or "we"; expresses stance; has takes and asides (essays, posts, reviews). → Drastic mode. Remove AI patterns AND add voice. Contract where natural (it's, don't, you've).
Mixed or unclear → default to conservative.
Classification signals: first-person markers above ~2 % of words → opinion. Proper-noun density above ~5 %, numbers / dates / citations present → encyclopedic. Imperative voice → conservative (technical).
Take positions - respond to facts instead of only stating them. Let rhythm move irregularly: a blunt sentence, then one that unwinds at its own pace; the enemy is a metronome in either direction. Acknowledge complexity, use "I" where it fits, and leave the small irregularities a person would - a digression, a parenthetical, an idea carried only as far as it needs to go. Be specific about feelings rather than generic.
Must survive every rewrite: numbers and units (0.19, 1989, 340 kg/m³, 55 %), proper nouns, hyphenated technical terms (thin-walled, load-bearing, strength-to-weight), citations, domain vocabulary.
Safe to paraphrase: hedges (typically, generally), generic passive verbs (results from, consists of), abstract property nouns when the domain term is also present, filler adverbs. Paraphrasing a hedge keeps the qualification and changes the wording; deleting the last one turns a qualified claim into an absolute one and is covered below.
Never invent: dates, statistics, quotes, named individuals, citations to sources not in the input. If specifics are missing, stay vague - do not supply plausible-sounding facts.
Never change what a statement asserts, who it belongs to, or how much of it there is. These are the failures that survive an entity check, because no number or name moves; every one was found in a real rewrite. Do not:
The bike weighs 23.2 lb is the writer's observation. Claimed weight is 23.2 lb attributes it to the manufacturer and is a different sentence. Never add claimed, reportedly, said to be or allegedly to something stated plainly, and never remove them from something attributed.there is the risk of over-diagnosis becomes an assertion that over-diagnosis happens if risk of is cut. Hedge stacking is pattern 54 and gets fixed by removing one hedge, never the last one.its small size makes it more of a deterrent than real theft prevention is a complaint. Reading it as the reason the lock works reverses the writer's judgment.30-hour battery life is not 30 hours of noise cancellation. Keep every figure attached to the thing it measured, especially in headings, subject lines and captions, where a reader sees it alone.[Name], {{first_name}} and [Your Company] are merge fields belonging to whatever system will fill them. Leave the token exactly as written, or leave the document alone.Domain-correctness check: every unusual word (≥ 7 letters, uncommon) in the rewrite must fit the surrounding domain vocabulary. Real-but-wrong words ("infantilization" appearing near vacuum-pressure / polymer terms) are harder to catch than typos and worse for credibility.
Character layer (§62, §66, §67, §68 in references/patterns.md): remove invisible and zero-width characters, normalize non-standard spaces to U+0020, trim stray trailing whitespace, fold mixed-script homoglyphs to ASCII (genuine non-Latin words untouched). Never strip legitimate \t / \n / \r inside the body. scripts/detect.py --clean applies all four deterministically.
Each pattern has a full Before / After in references/patterns.md (read it for the precise phrasing list when working a pattern). The numbering groups patterns by function; it folds the community-documented signs together with this project's additions rather than ordering them by origin.
--clean) - character layerWhen working on a specific pattern, read references/patterns.md and jump to the matching section for the exact phrasing list and Before / After.
Resolve the detector path first - scripts/detect.py is bundled in the skill directory, not the user's project, so a bare relative path will not resolve. Set DETECT once: as a plugin, $CLAUDE_PLUGIN_ROOT/scripts/detect.py; as a cloned skill, Glob **/sloptrim/scripts/detect.py (usually ~/.claude/skills/sloptrim/scripts/detect.py). Then run it before manual review:
python "$DETECT" input.txt # pass a path (works on all shells)
It emits JSON: pattern IDs with counts and samples, a _metrics block (rhythm statistics, contraction and passive ratios, character-layer counts), and ai_tell_score (0-100) with a band (clean / light tells / mixed / heavy tells / pervasive tells). The score weighs pattern diversity over raw density, floors when the character layer finds codepoints that carry no meaning in the text, and ignores copy-editing preferences. It is a triage heuristic, not a calibrated classifier.
A score describes the writing in front of it. It is not a judgement about who or what wrote a document, it cannot support one, and it must never be used to accuse a person of anything. See ETHICS.md. The 9 catalogue entries with no detector behind them (7, 9, 28, 29, 43, 45, 49, 52, 53) are worked by reading; even machine-checked ones deserve a reading pass for what the regex misses.
For the deterministic character layer, --clean emits the scrubbed text instead of JSON - it strips the invisible and non-printing codepoints, normalizes non-standard spaces to U+0020, folds mixed-script homoglyph letters back to ASCII (#66), and trims stray whitespace. Visible text is left alone. Trailing whitespace at the end of a line is not: it is removed, which will collapse a Markdown hard break if the draft used one. Only ever redirect this into a new plain-text file: given a .docx, .epub, .odt or .ipynb it prints the extracted text rather than a rebuilt document, so writing it back over the original would replace the document with loose text.
python "$DETECT" --clean gemini_nano_output.txt > clean.txt
Run it on any draft produced by another model to remove smuggled zero-width or TAG-block characters before the text ships.
Removing AI patterns is half the job; fill the space with patterns a person writes: active specific verbs (runs between, locks into - not serves as, provides); a short pivot sentence every 3-4 sentences that reframes the next idea; em-dash for contrast at most once per paragraph; the colon as an explanation hinge; concrete subjects ("Wind turbine blades rely on balsa" beats "Balsa is used in turbines"); specific judgments ("unusually high stiffness"); a final sentence that carries weight - a fact or real observation, never a generic positive close; varied paragraph length, one-sentence paragraphs allowed.
The catalogue folds publicly documented signs of AI writing with newer model-specific tells; all worked examples in references/patterns.md are original, and the lexical layer (#1) is the refresh point as model vocabularies shift. Scope is rewriting, not detection; defeating institutional integrity systems is out of scope. Version 0.9.3.
A local detector for AI-writing patterns. It scores the first 262,144 characters of extracted prose in files saved through supported file-edit tools, and asks for the flagged spans to be fixed. Plain text is accepted up to 512 KB, supported archives up to 4 MB. Python standard library only, no network, no model. Prose only, never code.
Install · What it does · Measured · Limits · Patterns · Ethics
[!IMPORTANT] This is a command-line tool and an agent plugin. There is no website and no hosted version. Nothing you write is uploaded, there is no account, and no text ever leaves your machine. Any site offering a service under this name is unrelated to this project.
Paste into Claude Code, Codex, Cursor, or any coding agent:
Install the sloptrim plugin from https://github.com/seyedehsanhadi/sloptrim
Restart, then run /sloptrim doctor. It answers with four [OK] lines.
/plugin marketplace add seyedehsanhadi/sloptrim
/plugin install sloptrim@sloptrim
git clone https://github.com/seyedehsanhadi/sloptrim.git ~/.claude/skills/sloptrim
mkdir -p ~/.claude/commands
cp ~/.claude/skills/sloptrim/install/sloptrim-command.md ~/.claude/commands/sloptrim.md
Do not skip the mkdir. On a fresh machine ~/.claude/commands does not exist yet
and the copy fails with "No such file or directory". In PowerShell the last two lines
are New-Item -ItemType Directory -Force $HOME/.claude/commands and Copy-Item.
The copy puts /sloptrim in the / menu, because Claude Code does not scan a skill
folder's own commands/. A marketplace install needs no such step. Either way the
router also answers to /sloptrim:sloptrim.
The score is 0-100 against 71 documented patterns. 62 of them have a detector; the other 9 need a reading and are worked during the rewrite. Of the 62, 50 can move the score and 12 are reported as writing advice and count for nothing: most of them because measurement showed they mark formal register rather than machine authorship, the rest because they are typographic habits.
| Formats | 20, including .docx, .pptx, .xlsx, OpenDocument, .epub, .ipynb, LaTeX; the first 262,144 characters of extracted prose is scored |
| Runs in | Claude Code, on save. Other agents via /sloptrim init, which writes the contract to AGENTS.md, and .cursor/rules/ |
| Needs | Node for the hooks, Python 3.9 or newer for the detector, nothing else |
| Suite | 142 Python tests and 72 hook checks, with CI configured for Linux, Windows and macOS, against Python 3.9 and 3.13 (macOS on 3.13) |
| Does not see | A file written by a Bash command, which reaches disk without passing Write or Edit |
| Command | Effect |
|---|---|
/sloptrim full |
Contract + guard (default) |
/sloptrim strict |
Flags at 20 instead of 40, and asks for a character scrub |
/sloptrim lite / off |
Contract only / nothing |
/sloptrim check <file> |
Score a file, name the tells, no rewrite |
/sloptrim init |
Write the contract to ./AGENTS.md and a Cursor rule to ./.cursor/rules/ |
/sloptrim doctor |
Diagnose the install |
python scripts/detect.py draft.docx # JSON: patterns, metrics, 0-100 score
A score lands in one of five bands: clean, light tells, mixed, heavy tells,
pervasive tells. The guard nudges above 40, or above 20 in strict mode.
Sloptrim's public matched benchmark uses five separate 30-human/30-machine arms
from the Human Detectors
release, pinned at commit afcf03d. Each arm is matched by prompt and scored
separately. AUC is a ranking measure, not accuracy at Sloptrim's guard threshold.
| machine arm | ROC-AUC | bootstrap 95% CI | default TPR / FPR |
|---|---|---|---|
| GPT-4o | 0.946 | 0.876–0.992 | 46.7% / 0% |
| Claude 3.5 Sonnet | 0.842 | 0.729–0.936 | 3.3% / 0% |
| o1-pro | 0.877 | 0.771–0.957 | 23.3% / 6.7% |
| paraphrased GPT-4o | 0.838 | 0.735–0.929 | 6.7% / 3.3% |
| humanized o1-pro | 0.762 | 0.648–0.871 | 0% / 3.3% |
Across these arms, Sloptrim achieved ROC-AUC 0.762–0.946. Confidence intervals use 10,000 paired prompt-cluster bootstrap resamples. The public result record pins the source hash; the harness refuses any other file. The benchmark texts are not redistributed here.
git clone https://github.com/jenna-russell/human_detectors.git
git -C human_detectors checkout afcf03d14d2da4a038d8d0fafa5ec779dd858181
python scripts/benchmark_frontier.py PATH_TO_HUMAN_DETECTORS_JSON
It cannot prove whether a model wrote something. The public arms show that the score often ranks these machine samples above matched human samples. The threshold results show why that is not the same as a dependable yes/no classifier: sensitivity changes sharply with model, prompt, formatting and threshold.
It is not an authorship classifier and must not be used as one. A score says something about writing, never about a person. Read ETHICS.md.
Apache-2.0 (full text, NOTICE). Cite with CITATION.cff.