Prose lint
SkillDev toolsAudit prose against .claude/rules/prose.md and apply the fixes.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Prose lint skill
About this capability
General library for AppleScript (JXA).
What this skill tells your AI
The instructions your AI receives, as published by tatsh/jxa-lib in .claude/skills/prose-lint/SKILL.md and read by ahel’s review.
Audit prose against .claude/rules/prose.md and apply the fixes.
Read that rules file in full before the first edit. This skill describes the procedure only; the rules file is the authority on what is banned.
Audit adversarially. When a sentence is defensible under a loose reading and a violation under a strict one, treat it as a violation. A borderline construction is rewritten, not excused, and doubt resolves toward the edit. Under-reporting is the failure mode to avoid. A grep hit stands until you can state which exemption in this file covers it.
Scope
Default target
Audit files with pending changes, from git status --porcelain and git diff --name-only HEAD.
When the user gives paths or a diff range, use those instead.
Audit every piece of prose inside each target file:
- Markdown body text, including headings, list items, table cells, and admonitions.
- Plain comments in any language.
- Formal documentation comments (Numpydoc, JSDoc, Doxygen, Javadoc, XML doc comments). The same standard applies to them as to Markdown body text.
- User-facing string literals such as log messages, help text, error messages, and CLI output.
- Commit messages under review.
Do not edit:
- Identifiers, code, URLs, file paths, and dependency names.
- Fenced blocks and italic examples inside
.claude/rules/prose.md. They exist to demonstrate violations. - Released
CHANGELOG.mdsections. Only theUnreleasedsection is in scope. - Quoted material from an external source. Flag it for the user instead.
Detection
Run the greps below over the target files, then review every hit by hand. Each grep over-matches by design; a noun spelled like a banned verb is valid, and the fix depends on the sentence.
grep -nP '\x{2013}|\x{2014}' <files>
grep -nEi "[[:alpha:]]+n[’']t\b|[[:alpha:]]+[’'](re|ll|ve|m)\b|\b(it|that|there|here|let|what|who)[’']s\b" <files>
grep -nEiw "gate|gates|gated|gating|stamp|stamps|stamped|stamping|answer|answers|answered|answering|say|says|said|saying|contain|contains|contained|containing|carry|carries|carried|carrying|hold|holds|held|holding|keep|keeps|kept|keeping|reach|reaches|reached|reaching|name|names|named|naming|lay|lays|laid|laying|leave|leaves|left|leaving|confine|confines|confined|confining|manufacture|manufactures|manufactured|manufacturing|claim|claims|claimed|claiming|ask|asks|asked|asking|transport|transports|transported|transporting" <files>
grep -nEi "\banyway\b|\banyone\b|\bnobody\b|\bno[ -]?one\b|\bobligatory\b|ground truth|elephant in the room|writing on the wall|beat around the bush|call it a day|cut to the chase|hit the nail on the head|jump on the bandwagon|think outside the box" <files>
grep -nEi ", (which|so|since|because)\b|says nothing|say nothing|for such|left alone|written by hand|that matters is|\bsomething\b|of (its|their|his|her) own|their own" <files>
Headings and titles need a separate pass:
grep -nE "^#{1,6} (The|What|Which|Whose)\b" <files>
grep -nEi 'either[.,;:!?)]*$' <files>
grep -nE "[a-z][a-z)\`_]: +[a-z]" <files>
grep -nE "\b(Ascii|Nasa|Nato|Unesco|Html|Css|Url|Api|Cli|Json|Yaml|Ssh|Http|Xml|Sql)\b" <files>
A colon that introduces a list of items is valid. Review each hit. A colon followed by a clause is the banned form, and the only permitted elaboration is a second sentence opening with That is,.
Two patterns need a read pass rather than a grep. Headings take the gerund-plus-pronoun form (Pointing an agent at it), and body text substitutes that, this, these, or those for a noun already available. A grep over the demonstratives over-matches so heavily as to be useless. Every restrictive clause and every legitimate determiner hits.
Fixing
- Rewrite each confirmed hit in place with
Edit. Preserve the meaning, the wrap width of the surrounding file, and the existing indentation. - Prefer deletion. A trailing justification clause, a vague follow-on sentence, and a (number) things worth ...: preamble are all removed rather than reworded.
- A banned verb usually disappears with the sentence restructured, not with a synonym dropped into the same slot. Verify the replacement reads naturally.
- Re-wrap any paragraph whose length changed, at the width the file already uses (100 characters for Markdown and Python in this repository).
- Never alter code, identifiers, or test expectations to make prose fit. When a string literal is asserted in a test, update the test in the same edit.
Verification
Run both commands and confirm exit code 0:
yarn format
yarn qa
Then re-run the detection greps. Report the remaining hits with a one-line justification each, or report a clean result.
Reporting
Give the user a short list of file, line, banned pattern, and the fix applied. Group by file. Do not add a summary paragraph beyond the list.
Signals
- GitHub stars
- 41
- Forks
- 3
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
prose-lint- Source
- github.com/tatsh/jxa-lib