Clean commit skill
Keep AI noise out of your git history. A cross-platform agent skill that blocks Co-Authored-By bots, generator footers, and model-name watermarks in commit messages β so git log, git blame, and changelogs stay signal, not spam.
npx -y skills add zyl100200/clean-commit-skillAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Writes git commit messages in a pure human-authored voice and strips AI attribution, tool watermarks, model names, co-author footers, and AI self-references. Use whenever creating, amending, rewriting, or reviewing a git commit message, including when running git commit, writing PR titles, or drafting commit bodies.
SKILL.md
7.9 KB, as published. Nobody here has run it
Clean Commit
Core rule
Commit messages describe the change, not the author's tooling. Never add AI/tool attribution to a commit message unless the user explicitly asks for it in the current turn.
Forbidden content
Before finalizing any commit message (subject + body + trailers), the message MUST NOT contain any of the following. Match case-insensitively.
1. AI co-author trailers
Any Co-Authored-By: line pointing to an AI assistant or bot account.
Examples to remove:
Co-Authored-By: Claude <[email protected]>Co-Authored-By: ChatGPT <...>Co-Authored-By: Cursor Agent <...>Co-Authored-By: GitHub Copilot <...>Co-Authored-By: Codex <...>Co-Authored-By: Gemini <...>- Any
Co-Authored-By:whose name or email references an AI product, assistant, bot, ornoreplyaddress of an AI vendor.
Real human Co-Authored-By: trailers are allowed and encouraged when appropriate.
2. Generator footers and watermarks
Any line that advertises the tool used to author the commit.
Examples to remove:
Generated with [Claude Code](https://...)Generated with Claude CodeGenerated by CursorGenerated by GitHub CopilotWritten by ChatGPTAuthored via <AI tool>Made with <AI tool>via Cursor,via Claude,via ChatGPT,via Copilot- Trailing URLs that promote an AI product (e.g.
https://claude.com/claude-code,https://cursor.com,https://openai.com/...) when used as an attribution link.
3. Bot emoji signatures
Emoji commonly used by AI tooling to mark generated output.
Examples to remove when they appear as a signature or prefix/suffix of a generator footer:
π€,π€ Generated ...π§ Generated ...β¨ Generated with ...
Normal content emoji inside a human-written message (e.g. :sparkles: in a gitmoji-style project) is fine.
4. Model and product names as authorship
Do not name the model or the AI product as the author.
Examples to remove:
Claude,Claude 3.5 Sonnet,Claude Opus,Claude Haiku,Claude CodeGPT,GPT-4,GPT-4o,GPT-5,o1,o3,o4Gemini,Gemini 2.5 ProCopilot,GitHub CopilotCursor,Cursor Agent,Cursor TabCodex,Devin,Aider,OpenCode
These names are only forbidden as authorship/attribution. If the change itself is about integrating such a product (e.g. feat: add Copilot webhook handler), the name is allowed as subject matter.
5. AI self-references in first person
Examples to remove:
As an AI, ...As a language model, ...I generated ...I wrote this commit ...by AI,AI-generated
6. Hidden watermarks
- HTML comments referencing AI:
<!-- generated by ... --> - Zero-width characters inserted as invisible markers.
- Tracking parameters on attribution URLs (e.g.
?utm_source=claude-code).
Allowed content
- Any normal commit subject and body describing the change.
- The project's existing conventions: Conventional Commits, ticket prefixes like
[NF],[PR],JIRA-123:, scopes, issue references,Fixes #123,Refs: .... - Real human
Co-Authored-By:trailers. Signed-off-by:trailers for the human committer.- Normal content emoji when the project uses them.
- Mentions of AI products when they are the subject of the change, not the author.
Pre-commit self-check workflow
Before running git commit, git commit --amend, or proposing a message to the user:
- Draft the message focusing on what changed and why.
- Scan the entire message (subject, body, trailers) for the forbidden items above, case-insensitively.
- If any match is found, remove the offending line or phrase and re-scan. Do not try to paraphrase an AI attribution into a "softer" AI attribution; delete it.
- Verify the final message still makes sense as a standalone human-authored commit. If deleting a trailer leaves a dangling blank section, clean that up too.
- Only then execute the commit or present the message.
When the agent itself invokes git commit -m "..." or uses a heredoc, the same scan applies to the exact string being passed.
IDE/CLI-level attribution (out-of-band)
Some IDEs or agent CLIs append their own trailer to commits after the message leaves the agent, by injecting flags like --trailer "Made-with: Cursor" into git commit. The resulting line appears in the committed message but was never part of the string the agent wrote, so the pre-commit self-check above cannot see it.
Detection:
- After any commit, if the agent has reason to verify the result (or the user reports a trailer they didn't expect), run
git log -1 --format=%Band scan that output against the same forbidden list. - Example tell-tale trailers injected by IDEs/CLIs:
Made-with: Cursor,X-Cursor: ..., vendor-specificX-<Tool>: ...lines.
When an out-of-band trailer is observed:
- Tell the user plainly: this line was added by the IDE/CLI, not written by the agent; the skill's message-content rules cannot block it. Point them at the README's "Known pitfall: IDE-level attribution" section for the exact fix for their tool.
- For Cursor specifically, the fix is two settings (IDE toggle and CLI config file). With the user's approval, the agent may apply the CLI config fix by writing
~/.cursor/cli-config.jsonwithcommitAttribution: falseandprAttribution: false. Do not apply it silently. - If the offending commit has not been pushed, offer to
git commit --amendwith the cleaned message after the injection source is disabled. If it has been pushed, follow the "Amending existing history" rules below β do not rewrite pushed history without explicit confirmation.
Amending existing history
Do not rewrite or force-push existing commits just to strip AI attribution from history. History rewrites are destructive and may not be wanted.
Instead:
- Keep all new commits clean.
- If the user notices old commits already contain AI attribution, mention that
git rebase -i/git filter-repocan scrub history, but only do it when the user explicitly asks and confirms the force-push implications.
Explicit user override
The only time AI attribution may appear in a commit message is when the user, in the current turn, explicitly asks for it (e.g. "add a Co-Authored-By Claude trailer"). Even then:
- Do not add extra attribution beyond what was requested.
- Do not add a generator footer unless the user asked for that specific line.
Do not infer consent from silence, from previous commits in the repo, or from a general "use Claude Code" setup.
Examples
Example 1 β feature commit
Bad:
feat(auth): add JWT refresh endpoint
Implements POST /auth/refresh with 15 min access / 7 day refresh tokens.
π€ Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Good:
feat(auth): add JWT refresh endpoint
Implements POST /auth/refresh with 15 min access / 7 day refresh tokens.
Example 2 β bug fix commit
Bad:
fix(reports): correct timezone off-by-one in daily rollup
Generated by Cursor Agent.
Good:
fix(reports): correct timezone off-by-one in daily rollup
Convert timestamps to UTC before bucketing so DST transitions no longer
shift a day's rows into the neighbouring bucket.
Example 3 β user explicitly requested AI co-author
User turn: "Commit this and add Co-Authored-By: Claude."
Acceptable:
refactor(db): extract connection pool into its own module
Co-Authored-By: Claude <[email protected]>
Still not acceptable (extra unrequested attribution):
refactor(db): extract connection pool into its own module
π€ Generated with Claude Code
Co-Authored-By: Claude <[email protected]>