39 screenshots and not one useful name, so a local Gemma names them for me A developer built slothshot, a ~230-line Go CLI that renames screenshots based on their visual content using Google's open-weight Gemma 4 E4B vision model, quantized to 4 bits and served locally through llama.cpp's llama-server. The tool preserves the original date prefix for sorting, defaults to a dry run, and supports -apply, -undo (via a .slothshot.tsv log) and -watch modes, with all inference kept on-device. The developer reported that disabling Gemma 4's default thinking mode with chat_template_kwargs fixed empty responses, and that raising image resolution from 1024 to 1536 px was needed to read a full 10-digit PNR correctly, at roughly 2.5 seconds per image instead of 1.3. This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady https://dev.to/challenges/hacktoberfest-week3-2026-10-19 slothshot renames screenshots after what's in them. Screenshot 2026-10-03 at 08.15.44.png becomes 2026-10-03 railbook-e-ticket-pnr-4421907736.png . My screenshots folder had 39 files in three naming schemes, because they came over from a Linux laptop: Screenshot from 2026-02-17 19-14-51.png , 2026-04-09 01-26-24.png and the macOS Screenshot 2026-10-17 at 13.34.06.png . None of them said what was in the picture. When I needed one, I opened thumbnails until I found it. Renaming them by hand would fix that, and I was never going to do it. So now a vision model on my laptop looks at each screenshot and picks a name: the app or site, and the specific thing on screen. The date stays at the front so the folder still sorts by time. It's for me, and for anyone whose Desktop looks like my Screenshots folder. Eight made-up screenshots a failing Go test, a flat group chat about the electricity bill, a UPI payment, a code review, a train ticket, a Grafana-style alert, a poha recipe and a macOS dialog : The default is a dry run. -apply renames, -undo puts every old name back from a log file in the folder, and -watch 1m keeps it running so each new screenshot gets a name within a minute of me taking it. It isn't perfect. It spelled SanDisk "sandsik". On the Go test it wrote "test-monthly-rollup-fail" and left out the actual panic, which is what I'd search for. On my own folder it named a black screenshot the-image-provided-is-completely-black , which is accurate. A name that's mostly right is still easier to search than Screenshot 2026-10-16 at 16.30.00.png . Renames your screenshots after what's in them. Screenshot 2026-10-03 at 08.15.44.png becomes 2026-10-03 railbook-e-ticket-pnr-4421907736.png , so Finder and Spotlight can find it when you type "pnr" three weeks later. A local open-weight vision model Gemma 4 E4B through llama.cpp looks at each picture. Nothing leaves your machine, which matters because screenshot folders are full of chats, bank pages and login screens. You need llama.cpp https://github.com/ggml-org/llama.cpp and Go. brew install llama.cpp llama-server -hf ggml-org/gemma-4-E4B-it-GGUF:Q4 0 --port 8092 -c 8192 go install github.com/omlahore/slothshot@latest slothshot ~/Pictures/Screenshots dry run, prints the new names slothshot -apply ~/Pictures/Screenshots renames them slothshot -undo ~/Pictures/Screenshots puts the old names back slothshot -watch 1m ~/Pictures/Screenshots leave it running, new screenshots get named as they land It only touches files with a default screenshot name: macOS Screenshot ... at ... , GNOME Screenshot from ... , Flameshot 2026-04-09 01-26-24.png , Android and CleanShot… The model is Gemma 4 E4B, Google's open-weight model that takes images, quantized to 4 bits the Q4 0 GGUF from ggml-org and served by llama.cpp's llama-server on localhost. The CLI is about 230 lines of Go with one dependency, golang.org/x/image, for resizing. For each file: -2 . Every rename is appended to .slothshot.tsv . Two things went wrong first. Every answer came back empty. Gemma 4 thinks before it answers by default, and with max tokens at 40 it spent all of them on "Thinking Process: 1. Analyze the Request". Passing chat template kwargs: {"enable thinking": false} turned that off, and answers came back in about a second. At 1024 px the model read the PNR 4421907736 as 44197736, two digits gone. A wrong PNR in a filename is worse than none, because you search for the right one and it isn't there. At 1536 px it read all ten digits. Each image now takes roughly 2.5 seconds instead of 1.3. A file gets renamed once, so I took the slower, correct version. I didn't think of my screenshots folder as private until I read the names slothshot proposed for it. There were chats with friends, video calls with other people's faces in them, and a few login pages. Naming those with a hosted API means uploading every one of them, and with -watch on, every new one as well. With Gemma on llama.cpp none of it leaves the laptop. It works with Wi-Fi off, and there's no per-image bill, so leaving it on to watch the folder costs nothing. The model is a 5 GB file on my disk. When a better open model comes out I change one flag, and if a provider retires this one next year, my copy keeps working. I ran it on my real folder in dry-run mode: -watch running from a LaunchAgent the plist is in the README , each one has a name by the time I go looking for it, and I don't lift a finger. -apply , it's typing "mailbox" or "pnr" into Finder. Nine of the 39 were screens from the same dashboard, and four of those came out with exactly the same name. -apply numbers them -2 , -3 and -4 instead of overwriting anything. Best Use of Gemma: slothshot runs Gemma 4 E4B open weights, GGUF on llama.cpp for every name it gives.