swipe
Skill4 starsChanged 5 months agoMITView on GitHub
Turn a pile of digital cleanup into a Tinder-style swipe deck on your phone. Point it at a folder (or your unread texts) and it serves a card deck to your phone over local WiFi. Swipe each card left or right, and the chosen action runs in one reversible batch at the end. Files swipe to Trash (recoverable, never deleted outright), texts swipe to skip or reply (replies are staged, never auto-sent). Cards show a real preview whenever possible, not just a filename, so you are never swiping blind. Built for the kind of task paralysis where 300 screenshots in a folder is easier to ignore than to face. Trigger on "/swipe", "let me swipe through my desktop", "swipe to clean out <folder>", "swipe my screenshots", "swipe my downloads", "swipe my unread texts", "give me a deck to clean out X".
- Deletes or force-pushes
2 other projects use a version of this.
Adopted by
Most recently taken up by
- geeks-accelerator/in-bed-aitheir own version, first seen Sep 29, 2026
- bartubozkurt/slideshows-factorytheir own version, first seen Aug 14, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- geeks-accelerator/in-bed-ai★ 26same name
- bartubozkurt/slideshows-factory★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository17 other files it gives its agents.
- ai-writing-qaSkill
- build-captureSkill
- build-modeSkill
- fitfoSkill
- flow-mapSkill
- generate-system-mapSkill
- imessageSkill
- leanSkill
- meta-promptSkill
- no-bullshitSkill
- plain-englishSkill
- pressure-testSkill
- problem-logSkill
- reality-checkSkill
- video-breakdownSkill
- viral-hook-creatorSkill
- working-with-claudeSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 21
Never make someone swipe blind: Every card should tell you enough to actually decide.
- Very specific: line 68
If you write a new adapter, try to give every item a thumb or a preview.
- Distinctive: line 72
Intake: Ask two things as a short multiple choice, not open-ended:
- Very specific: line 82
Gather items: Run the adapter, writing the manifest into the run dir.
- Distinctive: line 86
If the manifest has zero items, say there is nothing to swipe and stop.
- Distinctive: line 96
Wait: Stop and let them swipe. They will say "done" (or "stop") in chat.
- Very specific: line 105
If reply is non-null, that is the reply text for that handle.
- Very specific: line 106
If reply is null, draft a reply in the user's voice and pull context as needed.
- Very specific: line 115
Always wipe <skill>/.run/ at the end of a run.
- Distinctive: line 116
No em dashes in any output.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
swipe
A swipe-to-triage deck for digital cleanup. You point it at a source, it serves a card deck to your phone over your local WiFi, you swipe through the whole pile in one sitting, and the actions run as one reversible batch when you are done.
Why this exists
A folder with 300 screenshots is a wall. Cleaning it the normal way means 300 separate decisions, each with its own friction (open it, look at it, decide, find the next one), and that friction is exactly what task paralysis feeds on. So the folder just sits there, growing.
This collapses every decision into one flick of a thumb. One card, one swipe, next card. The deck shows up on your phone, so you can do it on the couch instead of staring at a file manager. Each swipe is its own tiny hit of done, and the momentum carries you through the pile that you would otherwise never start. Nothing is destructive in the moment: files go to the Trash (recoverable), text replies are staged for you to send later. The payoff is fast and visible, and you can undo.
Design rules that make it work, do not break them:
- Push, not pull. It loads the whole pile and hands it to you. It never makes you come back to fetch more.
- No guilt, no streaks, no counters that shame you. Just the deck and a running position.
- Reversible. Trash, not delete. Staged replies, not sent messages.
- One uninterrupted session. See below.
- Never make someone swipe blind. Every card should tell you enough to actually decide. See Previews below.
The engine is source-agnostic
The server and deck do not know or care what they are showing. They render whatever a manifest describes. A "source" is just an adapter script that emits that manifest. v1 ships two adapters (Files and iMessage); adding a new source (Gmail, Photos, a download queue, anything) is one new adapter that emits the same schema. That is what "point it at anything" means here.
Manifest schema (the contract)
{
"source": "files",
"title": "Downloads cleanup",
"left": { "label": "Trash", "kind": "trash" },
"right": { "label": "Keep", "kind": "keep" },
"reply": false,
"items": [
{
"id": "0",
"type": "image | file | text",
"label": "headline (file/image card)",
"sub": "subline, e.g. size and date, or a timestamp",
"path": "/abs/path (files: needed for thumbnail + action)",
"thumb": true,
"preview": "inline text preview shown on the card (files or text)",
"sender": "headline for a text card",
"handle": "who to reply to (text)",
"row": 123
}
]
}left/rightset the two swipe actions and their on-screen labels.kindis a free-form tag your executor reads.reply: truemakes each text card show a reply box.typecontrols the card:imageandfileboth render an image thumbnail frompathwhenthumbis true;textrenderssender+preview.idmust be a unique string. Decisions come back keyed byid.
Previews: never swipe blind
A card with nothing but a filename is a coin flip, not a decision. The Files adapter tries hard to give every card something real to look at:
- Images get a real thumbnail (resized via
sips). - PDFs, videos (
.mov/.mp4/...), Office docs (.pptx/.docx/.key/...), and.svgget a real thumbnail too, rendered on macOS by QuickLook (qlmanage -t) - first page of a PDF, poster frame of a video, first slide of a deck. SVGs are served directly since a browser can already render them. - Text-like files (
.txt,.md,.json,.py,.jsx, source code, etc.) get an inline text snippet instead of a thumbnail. .ziparchives get a contents listing (file names inside) instead of nothing.- Anything else falls back to a plain file icon - that is the one case where the adapter genuinely has nothing better to show.
If you write a new adapter, try to give every item a thumb or a preview. An icon-only card is a last resort, not the default.
Flow
- Intake. Ask two things as a short multiple choice, not open-ended:
- Source: a folder (offer Desktop, Downloads, screenshots, or a custom path) or unread texts.
- Screenshots is a special folder source. Screenshots save to the path in
defaults read com.apple.screencapture location(defaults to~/Desktop). Point the Files adapter at that folder, then filter the manifest items to screenshot-named files only (case-insensitive regexscreenshot|screen shot|cleanshot|screen recording) and renumber their ids0..nbefore serving. Keep each item's realpathso trashing still works. The action pair is implied by the source (files: Keep vs Trash; texts: Reply vs Skip), so do not ask a separate question about it. Always load the FULL pile in one deck. Never cap it or drip-feed. The entire point is one uninterrupted swipe session; making someone come back to load "the next batch" kills the momentum that got them started. Only chunk if a set is genuinely huge (hundreds and up) and a single page would choke the phone, and if so, say so out loud. Default sort is oldest-first; do not ask unless they want largest-first.
- Preflight.
- Network: the deck is served to the phone over the local network, so the phone just needs to be on the same WiFi as the computer. The server auto-detects the LAN IP (
ipconfig getifaddr en0, falling back toen1,en2). If you are on a VPN, do not hand the phone a VPN-only address; pass--host <lan-ip>explicitly or run on the computer's own browser with--host 127.0.0.1. Re-check the LAN IP if the phone can't connect - it can change mid-session (network switch, VPN toggle). - iMessage source only: reads
~/Library/Messages/chat.db, which needs Full Disk Access for the terminal. If the adapter errors on permission, surface that.
- Network: the deck is served to the phone over the local network, so the phone just needs to be on the same WiFi as the computer. The server auto-detects the LAN IP (
- Gather items. Run the adapter, writing the manifest into the run dir. Use a high
--cap(e.g. 1000) as a sanity ceiling only, never as a drip limit:- Files:
python3 <skill>/adapters/files.py "<folder>" --cap 1000 --sort oldest > <skill>/.run/manifest.json - Screenshots: gather as Files against the screenshot folder, then filter and renumber as in Intake.
- Texts:
python3 <skill>/adapters/imessage.py --cap 1000 > <skill>/.run/manifest.jsonIf the manifest has zero items, say there is nothing to swipe and stop.
- Files:
- Start the server in the background:
python3 <skill>/server.py <skill>/.run/manifest.json &It writes<skill>/.run/server-info.jsonwith theurl. Pass--host <lan-ip>if auto-detection picked the wrong interface. - Hand off to the phone. Open the QR page on the computer so it can be scanned:
open "<url>qr"(the url ends in/, so this opens.../qr). Also print the plainurlas a typeable fallback. Tell them: scan, swipe the deck, hit Done, then come back and say "done." The phone only needs to be on the same WiFi. - Wait. Stop and let them swipe. They will say "done" (or "stop") in chat.
- Read decisions from
<skill>/.run/decisions.json. Sanity check: the number of decisions should be at most the number of manifest items. If it is wildly off (e.g. zero), say so and ask before acting. - Execute the batch by source. The reversible parts run without an approval gate; the irreversible part (sending texts) always waits:
- Files: collect every manifest item whose decision
dir == "left", mapid -> path, and pipe the path list to the trash executor:echo '<json array of paths>' | python3 <skill>/trash_files.pyReport the returnedtrashedcount and anyfailed. - Texts: for every decision with
dir == "right":- If
replyis non-null, that is the reply text for thathandle. - If
replyis null, draft a reply in the user's voice and pull context as needed. Collect all(handle, reply)pairs. Do not send. Present them as a numbered list of staged replies and wait. Only on an explicit "send it" do you send each (e.g. via the local iMessage send path).dir == "left"texts are skipped, no action.
- If
- Files: collect every manifest item whose decision
- Report one plain line, e.g. "41 trashed, 12 kept. 5 replies queued (3 yours, 2 I drafted), say 'send it' to send them." Then shut down the server (kill the background process) and wipe the run dir:
rm -rf <skill>/.run/*. This is required..run/can hold message bodies and must never persist.
Hard rules
- Files go to Trash via the file manager (Put Back preserved), never
rm. - Texts are never auto-sent. Replies (typed or drafted) are staged; sending waits for "send it."
- Always wipe
<skill>/.run/at the end of a run. Message bodies must not persist anywhere. - No em dashes in any output.
Platform notes
Thumbnails (sips for images, qlmanage for PDFs/video/Office docs), Trash (Finder via osascript), and the iMessage source (chat.db) are macOS-specific. The server and deck themselves are plain Python and a single HTML file, so a new adapter plus a new executor could target another OS without touching the engine.
Adding sources later
A new source is one adapter emitting the manifest schema above, plus one executor for its swipe-left action. Sketches:
- Gmail: list = unread threads; card = sender + subject + snippet; left = archive, right = keep.
- Photos: deferred. Library deletion via automation is unreliable.
Credits
The phone handoff QR code is generated by the bundled vendor/qrcode.js, a third-party library by davidshimjs, Copyright (c) 2012, MIT licensed. Its full license text is bundled at vendor/LICENSE-qrcodejs.txt. Everything else is original.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

