{"id":"2aa0ea9f-2b7b-4c58-96b2-388b6859b600","slug":"chat-wrapped","kind":"skill","name":"chat-wrapped","summary":"Turn any WhatsApp chat into a year-in-review story you can share, and search it like an agent would.","owner":"Dodai0419","repoUrl":"https://github.com/Dodai0419/chat-wrapped","license":"MIT","licenseTier":"permissive","trust":"community","stars":0,"match":null,"fewStars":true,"format":"skill","createdAt":"2026-10-28T15:04:40.000Z","addedAt":"2026-10-30T04:01:50.219Z","logoUrl":"https://avatars.githubusercontent.com/u/130151547?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["communication","search","developer-tools"],"tags":["claude-code","codex","search","whatsapp","wrapped","year-in-review","claude-code-plugin"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-30T06:06:21.381Z","sample":false,"url":"https://conduits.dev/tools/chat-wrapped","language":"Python","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<div align=\"center\">\n\n# chat-wrapped\n\n**Turn any WhatsApp chat into a year-in-review story you can share, and search it like an agent would.**\n\nSpotify Wrapped for your group chat: who talks most, your hour, your words, your longest streak. It is made from the chat you export from WhatsApp, on your own computer, with the search rules of whatsapp-mcp and the decode-in effect of ascii-reveal.\n\n![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Status: prototype](https://img.shields.io/badge/status-prototype-orange.svg)\n\nWorks with **Claude Code** and **Codex**.\n\n<img src=\"docs/wrapped.png\" alt=\"Six story cards for the chat 'Maya & Leo': 4,261 messages on 238 days, who talks most, 22:00 is your hour, top words and emoji, a 10-day streak, and who writes first after a quiet night\" width=\"100%\">\n\n</div>\n\nThe picture above is the real output of `python chat_wrapped.py --demo --png`. The demo chat is made up ([examples/make_chat.py](examples/make_chat.py)). In the browser, every number and word on a card decodes into place.\n\n## Quick start\nIn WhatsApp, open a chat, tap the name, then **Export chat > Without media**, and save the `.txt`. Then:\n```bash\ngit clone https://github.com/Dodai0419/chat-wrapped && cd chat-wrapped\npython chat_wrapped.py \"WhatsApp Chat with Maya.txt\" -o out --png\n```\n```text\nchat-wrapped: 4,261 messages on 238 days (Maya 2545, Leo 1716); longest streak 10 days -> out/wrapped.html\nchat-wrapped: card-1..6.png and wrapped.png in out\n```\nOpen `out/wrapped.html`, or post `out/card-1.png` ... `card-6.png` (720 x 1280, the 9:16 story shape). One Python file, Python 3.8+ standard library only; `--png` needs Chrome or Edge.\n\n## Gallery\nEvery image is a real run on the made-up chats in [examples/](examples/).\n\n| Input | Cards |\n|---|---|\n| Two friends, iPhone export: `python chat_wrapped.py --demo -o docs --png` | ![](docs/card-1.png) ![](docs/card-3.png) |\n| The same chat, more cards | ![](docs/card-4.png) ![](docs/card-5.png) |\n| A five-person group, Android export (month/day, 12-hour clock): `python chat_wrapped.py examples/hiking-club.txt --title \"Hiking club\" -o docs/hiking --png` | ![](docs/hiking/card-2.png) ![](docs/hiking/card-6.png) |\n\nAll six group cards: [docs/hiking/wrapped.png](docs/hiking/wrapped.png).\n\n## Search it\n```bash\npython chat_wrapped.py chat.txt --search \"flight*\" '\"booked for thursday\"' CAFE --since 2026-03-01\n```\n```text\n## flight* (2 matches)\n[2026-12-21 22:44] Maya: the flights are booked for thursday ✈️\n...\n## CAFE (2 matches)\n[2026-12-29 18:33] Maya: found a café that does oat flat whites\n```\n| You type | It finds |\n|---|---|\n| `lease` | \"lease\" as a whole word, never \"release\" |\n| `CAFE` | café, Café, CAFÉ: case and accents are ignored |\n| `thursday flight` | messages with both words |\n| `\"booked for thursday\"` | those words together, in that order |\n| `flight*` | flight, flights, flighty |\n\nAdd `--sender NAME`, `--since` / `--until YYYY-MM-DD`, `--limit N`, or `--json` for one JSON object per hit. Several queries run in one pass over the chat.\n\n## The problem\n- WhatsApp has no year in review, and the stats sites want you to upload your private chat to them.\n- WhatsApp's own search matches inside words and has no phrases, so \"lease\" also finds \"release\".\n- A table of numbers is not something anyone shares; a story card is.\n\n## The solution\n| Idea | Fixes |\n|------|-------|\n| **Reads the export file on your machine** | Nothing is uploaded; the HTML is one file with no network requests |\n| **whatsapp-mcp's search rules** (whole words, accents folded, phrases, prefixes, newest first) | Search that finds what you meant, from the terminal or from your coding agent |\n| **Six story cards** sized for Instagram and WhatsApp Status | Something people actually post |\n| **ascii-reveal's decode** (a wave from the centre, a density ramp, then scrambled glyphs) with the real text always in the page | Cards that look alive, while screen readers read the real text and reduced-motion users get a short fade |\n\n## Use with Claude Code\n```bash\n/plugin marketplace add Dodai0419/chat-wrapped\n/plugin install chat-wrapped@chat-wrapped\n```\nThen ask: \"Make a wrapped story of my chat export ~/Downloads/WhatsApp Chat with Maya.txt\", or \"When did Leo say the flights were booked?\".\n\n## Use with Codex (ChatGPT)\n```bash\ngit clone https://github.com/Dodai0419/chat-wrapped && cp -r chat-wrapped/skills/* ~/.codex/skills/\n```\nOr copy [AGENTS.md](AGENTS.md) into your project root.\n\n## Options\n| Flag | What it does |\n|---|---|\n| `CHAT.txt` | the exported chat (iPhone or Android format, any date order) |\n| `-o DIR` | output folder (default `out`) |\n| `--title NAME` | name on the first card (default: the file name) |\n| `--year 2026` | only that calendar year |\n| `--dates dmy\\|mdy` | date order, when the guess is wrong (it is guessed from days above 12) |\n| `--png` | also `card-1.png` ... `card-6.png` and `wrapped.png` |\n| `--search Q ...` | search instead of making cards |\n| `--demo` | use the bundled made-up chat |\n\n## Benchmarks\nWindows 11, Python 3.11.1, `python bench/bench.py` (median of 5 runs per row; the script run 4 times on 2026-10-28, range shown, typical value in brackets) on the demo chat (4,261 messages). The numbers swing up to 2x with background load, so treat them as rough:\n\n| | upstream | chat-wrapped |\n|---|---|---|\n| search 4 queries in one pass | whatsapp-mcp: not run here (a Cloudflare Worker linked to your WhatsApp account; its docs say each search decrypts the history and \"takes a few seconds\") | 84-213 ms (~120) with `--limit 30`, 256-459 ms (~330) with no limit |\n| same answers | reference | the search checks in whatsapp-mcp's `test/store.test.mts` pass on the same messages (tests/test_chat_wrapped.py) |\n| parse the export | not part of whatsapp-mcp (it reads WhatsApp's live sync) | 34-103 ms (~45) |\n| stats + six cards | | 151-220 ms (~200) |\n| decode effect code | ascii-reveal `src/core/engine.ts`: 1,366 non-blank lines, React 17+ | 45 lines of plain JavaScript inside the page, for text only |\n| code for the search | whatsapp-mcp `src/store.ts`: 569 non-blank lines (store, encryption, search) and 5 dependencies | part of `chat_wrapped.py` (288 non-blank lines in all), no dependencies |\n\nWhat it does not do: whatsapp-mcp reads every chat live and keeps it encrypted; chat-wrapped reads one exported file. ascii-reveal also decodes images and skeleton loaders; chat-wrapped decodes text only.\n\n## FAQ\n**Is my chat uploaded?** No. The script reads the file and writes HTML and PNGs to the folder you choose. The page loads nothing from the internet.\n\n**Group chats?** Yes, up to six people get their own colour; everyone is counted.\n\n**Another language?** Search works in any script (the tests include Hebrew). The \"top words\" list skips common English filler words only.\n\n## Inspired by\n- [finereli/whatsapp-mcp](https://github.com/finereli/whatsapp-mcp): the query language and matching (fold, whole words, phrases, prefixes, newest first, batches that stop early) and its test cases.\n- [quanhoangindex/ascii-reveal](https://github.com/quanhoangindex/ascii-reveal): the `decode` preset (ramp, scramble glyphs, 60 ms tick), the `fast` timing (wave at 3.2 px/ms, 220 ms cap, 90-200 ms per character), ~30 fps repaint, real text kept in the DOM, reduced-motion fade.\n\n## Roadmap\n- [ ] Telegram and Signal exports\n- [ ] A \"you two vs the group\" card for group chats\n- [ ] An animated video export of the cards\n\n## License\nMIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).\n"}