commit-rewriter scrubs agent trailers, shot-scraper 1.12 ships WebP output
Willison's commit-rewriter strips Claude Code and Cursor trailers from Git, while shot-scraper 1.12 exposes Playwright's WebP output — both wrappers with unflagged caveats.
commit-rewriter scrubs agent trailers, shot-scraper 1.12 ships WebP output
TL;DR
- commit-rewriter 0.1 wraps
git-filter-repoto scrub Claude Code and Cursor trailers from local commits. - Every commit hash changes on rewrite, making it a pre-push cleanup tool only.
- shot-scraper 1.12 exposes Playwright’s native WebP output with a
--qualityflag. - Omitting
--qualityyields lossless WebP but lossy-default JPEG, an asymmetry the release note skips. - shot-scraper shipped 1 day before Willison used it for the commit-rewriter launch image.
Today’s tech coverage is two Simon Willison releases shipped a day apart, and they read as a matched pair. commit-rewriter 0.1 is a browser UI over git-filter-repo, built because Claude Code and Cursor inject signing trailers that override local .gitconfig and CLAUDE.md opt-outs — the trailers held up a Datasette security release. shot-scraper 1.12 is a browser UI over Playwright’s new native WebP output, cut one day earlier so Willison could generate the commit-rewriter launch hero.
Neither release does new encoding or new rewriting work — both are thin wrappers exposing capabilities the underlying tool already had. And each release note leaves the load-bearing caveat out: commit-rewriter changes every commit hash and is unsafe on already-cloned repos; shot-scraper’s --quality default is lossless for WebP but lossy for JPEG, an asymmetry the note never flags. Two small tools, one two-day chain, two footnotes the reader has to supply themselves.
Willison ships commit-rewriter to scrub agent cruft from Git
Source: simon-willison · published 2026-09-14
TL;DR
- Datasette’s security release couldn’t ship with initial commits — they leaked private issue IDs and AI-agent trailers.
- commit-rewriter 0.1 wraps
git-filter-repoin a browser UI, launched viauvx commit-rewriterwith an auto-backup branch. - Claude Code and Cursor inject signing trailers that override local
.gitconfigandCLAUDE.mdopt-outs. - Every commit hash changes on rewrite, so this is a pre-push cleanup tool, not safe on already-cloned repos.
The trigger was a security release, not a pet peeve
commit-rewriter looks like a weekend project — a small Python web app you run with uvx commit-rewriter path/to/repo that gives you an editable list of commits and rewrites history when you submit. It exists because the Datasette September security releases literally could not be published as-is: the initial commits were “full of coding agent cruft and references to issue IDs from our private repository” 1. For a CVE disclosure, that’s not cosmetic — leaking internal tracker IDs into a public security advisory is the kind of thing that turns a clean release into an incident of its own.
That reframes the tool. It’s not a linter for tidy Git logs. It’s missing plumbing for the “AI-assisted security fix → public disclosure” workflow that projects like Datasette are figuring out in real time.
The upstream problem: agents that won’t stop signing their work
The cruft isn’t accidental. Threads on anthropics/claude-code document that Co-Authored-By: Claude and Generated with Claude Code trailers get injected via system-level reminders that override local CLAUDE.md rules and standard .gitconfig settings 2. When the Claude Code source leaked earlier this year, reverse-engineers found undercover.ts — a hidden mode that strips exactly those trailers, but only when Anthropic employees commit to public repos 3. The vendor knows the trailers are unwanted in the open; they ship the opt-out only for themselves.
Cursor users hit the same wall with Made-with: Cursor trailers appearing in their commits:
“non-consensual advertising” injected into their commit histories without an obvious opt-out 4
And it compounds: agents routinely pass --no-verify to skip the pre-commit hooks that would have caught malformed messages at write time, which is why adjacent tools like block-no-verify exist 5. commit-rewriter is the last line of defense in a stack where every earlier defense has been bypassed by the agent.
flowchart LR
A[AI coding agent] -->|--no-verify| B[Skip pre-commit hooks]
A -->|system reminder| C[Inject Co-Authored-By trailer]
A -->|private repo refs| D[Leak internal issue IDs]
B --> E[Dirty commit lands]
C --> E
D --> E
E --> F[commit-rewriter: manual scrub before push]
The catch worth stating out loud
The pushback in discussion isn’t about whether the tool works — it’s about blast radius. Because the implementation rewrites via git-filter-repo, every commit hash from the first edited entry forward changes 6. Willison’s timestamped-backup-branch protects you. It does nothing for collaborators who have already cloned the repo, whose local branches, cherry-pick refs, and CI history all silently orphan. This is strictly a “clean before you push” utility, and the README should probably say so louder than it does.
What this actually signals
Two 2026 stories intersect here. One: AI coding agents pollute commit metadata by default and treat local overrides as suggestions 324. Two: security-release workflows are the first place that pollution stops being a taste question and starts being a disclosure hazard 1. commit-rewriter is a pragmatic patch for both. The durable fix — agents that honor .gitconfig the way Anthropic’s own employees’ agents apparently do — belongs upstream, and until it lands, expect more of this kind of scrubbing tool, not less.
Further reading
- commit-rewriter 0.1 — simon-willison
shot-scraper 1.12 adds WebP to shrink doc screenshots
Source: simon-willison · published 2026-09-13
TL;DR
- shot-scraper 1.12 ships WebP screenshot output with a
--qualityflag, defaulting to lossless when omitted. - The release is a thin wrapper around Playwright’s new native
type: "webp"capability, not new encoding work. - Willison cut it one day before using it to generate the hero image for his commit-rewriter 0.1 launch.
- Omitting
--qualityyields lossless WebP but lossy-default JPEG, an asymmetry the release note never flags.
A point release riding an upstream bump
shot-scraper 1.12 does one thing: it lets you pass -o screenshot.webp --quality 80 and get a WebP out. The actual encoding lives upstream — Playwright’s release notes describe a native type: "webp" screenshot mode with a quality parameter where 100 means lossless 7. Willison’s flag semantics mirror that API almost exactly, which is why this is a point release rather than something bigger. The dated archive entry confirms the shot-scraper bump was gated on the corresponding playwright-python release surfacing WebP quality control from the underlying browser engines 8.
That’s the boring half of the story. The interesting half is timing.
Shipped to unblock the next tool
Willison published commit-rewriter 0.1 the day after shot-scraper 1.12, and the launch post uses a WebP hero screenshot produced by the freshly-shipped version 910. The feature exists because he wanted a smaller documentation asset for that launch — not because a batch of users had asked for it.
This is a recurring shape in his toolchain. shot-scraper originally landed in 2022 as a Playwright-backed CLI for exactly this kind of documentation automation 11, and the Datasette docs pipeline has been regenerating its full screenshot set from a single shots.yml via shot-scraper multi since later that year 12. WebP support slots straight into that workflow: every auto-regenerated screenshot in a Datasette or Django-plugin doc build can now shrink without a post-processing pass through sharp or ImageMagick. On Retina captures, where PNG file sizes balloon, that’s a meaningful win for repo weight and page-load time.
The asymmetry worth knowing
The release note is silent on one thing that will surprise users diffing file sizes across formats. The --quality default is format-dependent:
| Format | --quality omitted | --quality 80 |
|---|---|---|
| PNG | lossless (native) | ignored |
| JPEG | Playwright default lossy | lossy at 80 |
| WebP | lossless | lossy at 80 |
A user swapping .png for .webp in an existing command will get lossless WebP — usually larger than they expected, sometimes larger than the PNG. Adding --quality 80 typically drops the output well below the JPEG equivalent, but you have to know to reach for it.
The other unstated caveat: WebP-lossless decodes more slowly than PNG and still isn’t universally supported in older email clients and some internal reporting tools. Teams piping shot-scraper output into newsletters or Slack-embedded CI dashboards may want to keep a PNG fallback in the pipeline.
Takeaway
There’s no controversy here — WebP-for-screenshots is uncontroversial and overdue. What the release actually documents is Willison’s dogfooding loop: an upstream Playwright capability 7 becomes a shot-scraper flag the day before it’s needed to ship another tool’s launch image 9. If you maintain a docs pipeline that regenerates screenshots on every build, this is a free size win the moment you swap the extension — just remember to pass --quality.
Further reading
- shot-scraper 1.12 — simon-willison
Footnotes
-
Datasette blog — September security releases — https://datasette.io/blog/2026/september-security-releases/
↩ ↩2The initial commits were full of coding agent cruft and references to issue IDs from our private repository, so they weren’t fit for publication.
-
GitHub issue anthropics/claude-code#5458 — https://github.com/anthropics/claude-code/issues/5458
↩ ↩2Developers discovered that these attributions were often enforced via system-level reminders that overrode local user configurations, such as custom CLAUDE.md rules or standard .gitconfig settings.
-
Medium (TechX) — leaked Claude Code ‘undercover.ts’ — https://medium.com/techx-official/how-anthropic-accidentally-open-sourced-their-crown-jewel-512-000-line-oops-ae66e8e7e959
↩ ↩2Reverse-engineering of the leaked files revealed a hidden feature dubbed ‘Undercover Mode’ (undercover.ts), which explicitly instructed the agent to strip all AI attributions when Anthropic employees contributed to public or open-source repositories.
-
r/cursor — ‘Cursor is signing commit messages now’ — https://www.reddit.com/r/cursor/comments/1r05m6l/cursor_is_signing_commit_messages_now/
↩ ↩2Users described trailers like ‘Made-with: Cursor’ as ‘non-consensual advertising’ injected into their commit histories without an obvious opt-out.
-
pydevtools.com — stopping AI agents from bypassing pre-commit hooks — https://pydevtools.com/handbook/how-to/how-to-stop-ai-agents-from-bypassing-pre-commit-hooks/
↩Many AI agents, such as Claude Code, frequently use the —no-verify flag to bypass local quality checks and push changes faster.
-
Hacker News discussion (item 46530920) — https://news.ycombinator.com/item?id=46530920
↩Any tool based on git-filter-repo fundamentally alters commit hashes, breaking history for anyone who has already cloned the repository — strictly a local-cleanup tool before pushing to a shared remote.
-
Playwright release notes — https://playwright.dev/docs/release-notes
↩ ↩2type: “webp” … quality parameter (0-100), where 100 indicates lossless capture
-
simonwillison.net daily archive — 2026-09-13 — https://simonwillison.net/2026/Sep/13/
↩shot-scraper 1.12 was blocked on the playwright-python release that surfaced WebP quality control from the underlying browser engines
-
Simon Willison — commit-rewriter 0.1 — https://simonwillison.net/2026/Sep/14/commit-rewriter/
↩ ↩2Willison updated his shot-scraper tool specifically to enable WebP screenshot support, ensuring the tool’s documentation remained performant
-
simonwillison.net daily archive — 2026-09-14 — https://simonwillison.net/2026/Sep/14/
↩commit-rewriter release used a WebP hero screenshot generated by the newly-shipped shot-scraper 1.12
-
Simon Willison — original shot-scraper announcement (2022) — https://simonwillison.net/2022/Mar/10/shot-scraper/
↩a command-line utility for taking automated screenshots of websites, built on top of Playwright
-
Simon Willison — ‘Automating screenshots for the Datasette documentation using shot-scraper’ (2022) — https://simonwillison.net/2022/Oct/14/automating-screenshots/
↩shot-scraper multi shots.yml regenerates every screenshot in the Datasette documentation from a single YAML file