{
  "markdown": "<p align=\"center\">\n  <img src=\"assets/enuff-is-enuff.png\" alt=\"enuff is enuff\" width=\"240\">\n</p>\n\n# enuff-is-enuff-unsubscribe\n\nA blunt, local-first inbox cleanup workflow for Claude Code.\n\n## What it does\n\nClaude scans an exported mailbox, ranks the senders that won't leave you alone — newsletters you never read, ecommerce promos, abandoned SaaS drips, \"we miss you\" campaigns, zombie senders — and helps you unsubscribe one item at a time, with your approval, locally, without ever touching your live inbox.\n\nInspired by `just-fucking-cancel`: Claude does the annoying digital chores, you stay in charge.\n\n## Install\n\nPick whichever fits — both run the same workflow with the same safety rules.\n\n### Option 1 — install as a Claude Code plugin\n\nPlugin mode gives you slash commands that work from any directory.\n\n**From the public repo** (recommended):\n\n```text\n/plugin marketplace add codecoincognition/enuff-is-enuff-unsubscribe\n/plugin install enuff-is-enuff-unsubscribe@enuff-is-enuff-local\n/reload-plugins\n```\n\n> **Note:** `enuff-is-enuff-local` is the marketplace name (defined in `.claude-plugin/marketplace.json`), not a typo. The format is always `plugin-name@marketplace-name`.\n\n**From a local clone** (when you're modifying the plugin):\n\n```bash\ngit clone https://github.com/codecoincognition/enuff-is-enuff-unsubscribe.git\n# then, in Claude Code:\n/plugin marketplace add ./enuff-is-enuff-unsubscribe\n/plugin install enuff-is-enuff-unsubscribe@enuff-is-enuff-local\n/reload-plugins\n```\n\n**Or load directly without installing** (fastest for development — no copy to cache):\n\n```bash\nclaude --plugin-dir ./enuff-is-enuff-unsubscribe\n```\n\nOnce loaded, slash commands work from any directory:\n\n```text\n/enuff-is-enuff-unsubscribe:scan <path-to-mbox-or-eml-folder>\n/enuff-is-enuff-unsubscribe:review\n/enuff-is-enuff-unsubscribe:act\n```\n\nIf you edit any plugin file after installing, run `/reload-plugins` again to pick up the changes without restarting Claude Code.\n\n### Option 2 — download the repo and let Claude walk you through it\n\nNo plugin install, no git required.\n\n1. Go to [github.com/codecoincognition/enuff-is-enuff-unsubscribe](https://github.com/codecoincognition/enuff-is-enuff-unsubscribe).\n2. Click the green **Code** button → **Download ZIP**.\n3. Unzip it (double-click on Mac; right-click → Extract on Windows). You'll get a folder named `enuff-is-enuff-unsubscribe-main`.\n4. Move it somewhere easy to find — your Desktop works.\n5. In a terminal:\n\n```bash\ncd ~/Desktop/enuff-is-enuff-unsubscribe-main\nclaude\n```\n\nThe repo's `CLAUDE.md` auto-loads and walks Claude through the scan → review → act flow using the local `bin/enuff_scan.mjs`. Just say \"I want to clean up my inbox\" or paste an mbox path. No slash commands needed.\n\nIf you have git, the one-liner equivalent is:\n\n```bash\ngit clone https://github.com/codecoincognition/enuff-is-enuff-unsubscribe.git && cd enuff-is-enuff-unsubscribe && claude\n```\n\n### Browser control (strongly recommended)\n\nThe act phase actually drives Chrome to flip the right toggles or click the right confirm buttons, then verifies completion by reading the DOM. Without browser control, the plugin runs in **degraded mode** — it can open unsubscribe URLs in your browser, but you click the toggles yourself, and nothing is verified.\n\nTo enable real automation, install **Claude for Chrome** (Anthropic's official Chrome extension + MCP):\n\n1. Get the extension from [claude.com/product/claude-for-chrome](https://claude.com/product/claude-for-chrome) and follow the install steps there.\n2. Confirm it's registered with Claude Code by checking that the `mcp__claude-in-chrome__*` tool family appears in any new session (e.g., run `/mcp` in Claude Code to list active MCP servers).\n3. In any Claude Code session, you can also test with `/chrome` — it should attach to your running Chrome and open a tab.\n\nOnce installed, the act phase navigates each approved unsubscribe URL, identifies the provider (Substack settings page, Mailchimp confirmation page, Beehiiv one-click, etc.), clicks the right control, and reads `aria-checked` (or equivalent DOM state) to verify the unsubscribe really happened. Every action is screenshotted into the action log.\n\n**Compatible alternatives** that expose navigate/click/read-DOM/screenshot also work: gstack `/browse`, custom CDP-based MCPs, etc. The plugin uses generic browser-control patterns, not Anthropic-specific APIs.\n\n**Without any browser-control MCP**, the plugin still runs — it falls back to `open <url>` for each approved item and tells you exactly what to click. It's slower, no verification, but safe and universal.\n\n### Try it without your real inbox\n\nThe repo ships with a sample inbox at `examples/sample-inbox/` — 209 fake `.eml` files across 55 brands spanning every classifier category. Perfect for trying the brand-by-brand review before pointing it at your actual mail.\n\n| Plugin mode | `/enuff-is-enuff-unsubscribe:scan examples/sample-inbox` |\n| Directory mode | Just tell Claude: *\"scan examples/sample-inbox\"* |\n\n## How it works\n\nThe workflow is the same in plugin mode and directory mode. Only the entry points differ.\n\n### 1. Scan\n\nYou give the path to an exported mailbox (Gmail Takeout `.mbox`, Apple Mail `.mbox` package's inner `mbox` file, Thunderbird `.mbox`, or a folder of `.eml` files).\n\n| Plugin mode | Run the slash command: `/enuff-is-enuff-unsubscribe:scan ~/Downloads/INBOX.mbox/mbox` |\n| Directory mode | Just tell Claude: *\"Scan this mailbox: ~/Downloads/INBOX.mbox/mbox\"* |\n\nThe scanner reads only message headers (no body, no attachments) and writes:\n\n```text\nenuff-is-enuff-report/\n  report-state.json        canonical scan state\n  approved-actions.json    canonical approval state (all approved=false initially)\n  sender-ranking.csv\n  recommended-actions.md\n```\n\n`report.html` is *not* written until after review. Nothing is acted on yet.\n\n### 2. Review (in Claude chat — the approval surface)\n\n| Plugin mode | Run `/enuff-is-enuff-unsubscribe:review` |\n| Directory mode | Just say *\"walk me through the candidates\"* — `CLAUDE.md` routes to the same skill |\n\nClaude reads `report-state.json`, presents brands grouped by stream (marketing_promos, newsletter, saas_lifecycle, etc.), and **asks you which to flag** brand-by-brand. You can pick at the stream level — e.g. flag `Substack:newsletter` while keeping `Substack:marketing_promos`. Selection grammar: `Brand:stream`, `Brand:s1+s2`, `all newsletters`, `all newsletters except X`, or `none`.\n\nProtected streams (`account_security`, `orders_receipts`, `protected_high_risk`) are locked by safety rules and never appear in the prompt.\n\nYour selections write directly into `approved-actions.json`. Claude then renders `enuff-is-enuff-report/report.html` so you can see your approved items highlighted (green badge, green row, top summary panel listing every approval).\n\n`report.html` is **read-only** — it is a confirmation surface, not an interactive control panel. Approval lives in the chat with Claude.\n\n### 3. Act (one global approval, browser-driven execution)\n\n| Plugin mode | Run `/enuff-is-enuff-unsubscribe:act` |\n| Directory mode | Just say *\"I'm ready to act\"* — `CLAUDE.md` routes to the `safe-action` skill |\n\nClaude first asks the global gate:\n\n```text\nHave you reviewed the report? Are you okay with everything?\n```\n\nBefore processing, Claude shows you the queue (count + a one-line per-item summary) so you have a final visual pass. **One global \"yes\" then authorizes the entire queue** — Claude does not ask again per URL, because the per-item decisions already happened during review.\n\nFor every approved item, Claude:\n\n1. **Navigates** to the URL via Chrome control.\n2. **Reads the actual rendered page** — never pre-classifies based on URL shape. A `disable_email?token=…` URL *looks* like a one-click endpoint but is actually a Substack settings deep-link. The plugin learned this the hard way; URL pattern matching produces false confidence.\n3. **States the action it's about to take, in one line** (e.g., *\"This is the Substack settings page; the 'Marketing emails' toggle is currently on; I'll flip it off\"*).\n4. **Executes** via real Chrome click events (synthetic JS clicks are dropped by some React component libraries — must use the real event path).\n5. **Verifies via DOM state** — `aria-checked` on toggles, page-text change, URL redirect. Body-keyword matching against the rendered HTML is forbidden; providers' SPA shells contain success/failure strings as JS bundles regardless of actual state.\n6. **Screenshots** the post-action page for the log.\n7. If the page state is ambiguous (login wall, unexpected popup, multiple plausible buttons), Claude does **not** click — it marks the item `needs your verification` and moves on.\n8. Mailto unsubscribes are drafted and `open \"mailto:…\"`-ed into the user's mail client pre-filled; the user presses send.\n9. Logs every action to `enuff-is-enuff-report/action-log.md` with DOM state before/after, recipe used, and screenshot reference.\n\nWhen the queue is drained, Claude posts an **end-of-act summary**: counts (completed / needs-verify / mailto-pending / failed), a per-item table with ✓/⚠/✗ icons, and any items still needing your attention.\n\n## Why it exists\n\nNormal unsubscribe tools give you a sender list. This plugin does something more useful:\n\n- **Distinguishes** newsletters from account/security/payment relationships, not just by domain but by header signals (`List-Unsubscribe`, `List-ID`) and subject keywords.\n- **Ranks** the worst offenders by volume, recency, and unread rate — so the loudest noise comes first.\n- **Explains** why each sender was flagged (recurring promo language, header-based unsub path, no-reply marketing domain, etc.).\n- **Picks the right action** per stream: token-URL one-click, multi-step browser flow, mailto draft, or filter-only.\n- **Refuses to touch** banking/security alerts, receipts, payroll, healthcare, or government senders — even if you accidentally select them.\n- **Keeps every irreversible action behind your approval**, with full action logs.\n\nThe product is not \"bulk unsubscribe.\" It's \"make the inbox stop harassing me, with judgment, and don't break the things I actually need.\"\n\n## Privacy & safety\n\nLocal-first by design — there is no server.\n\n- Mailbox exports stay on your machine. Nothing is uploaded.\n- The scanner reads only message headers (no bodies, no attachments).\n- No OAuth, no app passwords, no Gmail API. You hand over a file, not an account.\n- Account/security, financial, payroll, healthcare, and government senders are **locked** from the action queue automatically — even if you accidentally select them.\n- Every action is logged to `enuff-is-enuff-report/action-log.md` with a timestamp, the URL, the method used, and the verified outcome.\n- The plugin will never enter credentials, delete or archive messages, create filters, or send mail without your explicit approval.\n\nThe \"act\" phase opens unsubscribe URLs in your browser and drafts mailto messages — nothing else.\n\nFor the full audit-grade summary (network surface, credentials policy, data flow, file footprint, and source pointers), see [SECURITY.md](./SECURITY.md). For what's planned and what will never ship, see [ROADMAP.md](./ROADMAP.md).\n\n## What's in this repo\n\n```text\n.claude-plugin/plugin.json    plugin manifest (option 1)\nCLAUDE.md                     directory-mode entry point (option 2)\ncommands/                     slash command bodies (option 1)\nskills/                       canonical workflow skills (used by both options)\nagents/                       agent personas (used by both options)\nbin/enuff_scan.mjs            scanner / report renderer / serve (Node stdlib only)\nexamples/\n  sample.eml + receipt.eml + security.eml   minimal 3-message starter\n  sample-inbox/                             209 fake messages across 55 brands\nassets/                       logos + marketplace screenshots + capture recipe\nLICENSE                       MIT\ngetting-started.html          GitHub-renderable overview page\n```\n\n## Requirements\n\nOnly Claude Code. The scanner uses the Node.js standard library only — nothing extra to install.\n\n## License\n\nMIT — see [LICENSE](./LICENSE). Copyright 2026 Code Coin Cognition LLC.\n",
  "bytes": 12247,
  "sha": "7c0cc5ac1c4dbc86cc9e4430a91fe70218a1b35ce45f7e7a1b4d4966f85c76c7",
  "repo_slug": "codecoincognition/enuff-is-enuff-unsubscribe",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_codecoincognition_enuff_is_enuff_unsubsc_bde1e10e/readme"
}