Skip to content

Releases: bgorzelic/gmail-cleanup

v0.6.1 — stop on an exhausted Gmail quota

Choose a tag to compare

@bgorzelic bgorzelic released this 30 Sep 07:21
db33a13

Fixed

  • An exhausted Gmail quota stops the run instead of being retried. A 403
    dailyLimitExceeded (or quotaExceeded) now raises a clear error and exits
    with status 2. v0.6.0 treated quotaExceeded as a rate limit and retried it.

v0.6.0 — installable: pipx install gmail-inbox-cleanup

Choose a tag to compare

@bgorzelic bgorzelic released this 30 Sep 06:57
0efb4d9

The "installable" release. First release on PyPI, as gmail-inbox-cleanup
(pipx install gmail-inbox-cleanup); the command is still gmail-cleanup. The
gmail-cleanup name on PyPI belongs to an unrelated project.

⚠️ Upgrading from 0.5.x

  • Your lists moved. Lists now ship inside the package as seeds
    (gmail_cleanup/lists/), merged with your own copies in ~/.gmail_cli/lists/.
    Only keep.yaml ships populated; humans, kill and unsubbed ship empty.
    If you edited the repo's lists/*.yaml, copy humans.yaml, kill.yaml and
    unsubbed.yaml into ~/.gmail_cli/lists/ before upgrading.
  • Successful unsubscribes are now appended to ~/.gmail_cli/lists/unsubbed.yaml
    (previously the repo/package copy).

Fixed

  • verify no longer flags senders for mail sent before you unsubscribed.
    It counted every message in the last 14 days, including mail that arrived
    before the unsubscribe, so autopilot --escalate run daily would block-filter
    senders unsubscribed the day before. Entries with an unsubscribed_at
    timestamp now count only mail after that time plus a grace period
    (--grace-days, default 2 — Google's bulk-sender deadline). Senders still
    inside the grace period are reported as PENDING and are never escalated.
  • List and state writers: a sender could be silently dropped after an
    unterminated header comment; concurrent runs (scheduled + manual) lost records
    and crashed on rename; a failed write could strand the newer data; event
    deltas could overwrite a record's timestamp; malformed state files raised.
  • Wheel no longer installs a top-level lists/ directory into site-packages,
    and the sdist no longer sweeps in stray checkouts.
  • humans.yaml senders are never unsubscribed or archived. The docs promised
    this, but unsubscribe never checked the list. Humans now win over the kill
    list too.
  • Removed the has:list catch-all filter. has:list is not a Gmail search
    operator — the filter matched nothing. Delete it from your Gmail filters if a
    previous version created it.
  • filters apply replaces a grown list's filter instead of stacking another.
    Each run that added unsubscribed senders used to leave the older filter behind.
    Older filters are removed only when the new one covers every sender in them.
  • filters apply skips filters whose list is empty (Gmail rejects an empty from:).
  • status matches Gmail's UI: inbox conversations and inbox-only unread, from
    one API call. It used to page through up to 10,000 message IDs twice and count
    messages and all-mail unread.
  • Rate-limited or failed API calls are retried and reported instead of silently
    returning nothing.

Added

  • autopilot --days N and --min-count K to tune the unsubscribe phase
    (defaults unchanged: 30 days, 2 messages).
  • autopilot --email-summary emails the run's report to the account itself —
    e.g. a scheduled --dry-run preview.
  • verify --grace-days N.
  • Much faster scans that respect Gmail's quota. unsubscribe fetches headers
    in HTTP batches (25 per request) paced to the documented per-user limit
    (100 quota units/s), and no longer fetches each sender a second time.
  • Rate-limit handling: honors Retry-After, backs off 5→80 s with jitter,
    re-sends throttled items in smaller batches, and remembers a throttle in
    ~/.gmail_cli/ so autopilot skips its run until it expires.
  • Progress lines for non-terminal runs (logs, launchd).
  • Autopilot webhook notification (notify.webhook_url in config).
  • unsubbed.yaml mapping format {sender, unsubscribed_at}; bare-string
    entries are still read.
  • User override lists in ~/.gmail_cli/lists/ merged with the packaged seeds.
  • Tests for the scheduler, setup wizard, progress UI, list layout, verify
    windows and autopilot (200+ tests). Tests run with a sandboxed HOME.
  • CI gates on ruff check before pytest; PyPI trusted-publishing workflow.

v0.5.2 — README polish

Choose a tag to compare

@bgorzelic bgorzelic released this 16 May 08:03

Documentation patch release. No behavior changes.

What's new

  • README rewrite with hero badges (CI, release, Python, license), sample autopilot output, comparison table vs. other tools, three-bucket diagram, pipeline diagram, cleaner section structure with emoji anchors.
  • Stale references fixed: the setup wizard was described as "6-step" in three places. It's been 7-step since v0.5.1.
  • HANDOFF.md version line updated.

Same as v0.5.1

  • 84 tests passing
  • Setup wizard handles OAuth consent screen
  • TROUBLESHOOTING.md covers common first-run issues

Install

pipx install git+https://github.com/bgorzelic/gmail-cleanup.git

Full changelog: CHANGELOG.md

v0.5.1 — partner-handoff polish

Choose a tag to compare

@bgorzelic bgorzelic released this 16 May 07:53

Patch release. Closes the one real first-run gap from v0.5.0 and adds onboarding documentation.

What's new

  • Setup wizard adds Step 3/7: OAuth consent screen. Previously the wizard jumped from "enable Gmail API" straight to "create OAuth client", but Google requires the consent screen to be configured first — and unverified apps need the user added as a Test User. Without this step, new users hit "Access blocked: This app's request is invalid" on first run.
  • TROUBLESHOOTING.md covers the 6 issues new users hit most often: consent-screen errors, missing credentials, scope limits, scheduler on Linux/Windows, 7-day token expiry for unverified apps, PATH issues with pipx.
  • ARCHITECTURE.md — 5-minute tour of the codebase for new contributors.
  • CI workflow runs pytest matrix across Python 3.11/3.12/3.13 on every push and PR.
  • Issue templates for bug reports and feature requests.

Changed

  • README install section now leads with pipx install git+https://github.com/bgorzelic/gmail-cleanup.git (the right choice for end users) instead of the clone-and-pip-install path (which stays, for contributors).
  • CONTRIBUTING.md adds a "First-time onboarding" section pointing new collaborators at ARCHITECTURE.md and the safety invariants.

Compatibility

No behavior changes for existing v0.5.0 users. 84 tests still passing.

v0.5.0 — Swiss army knife release

Choose a tag to compare

@bgorzelic bgorzelic released this 16 May 07:45

The "Swiss army knife" release. Eight new components across four layers — config foundation, quick wins, features, and onboarding.

What's new

  • gmail-cleanup setup — interactive 6-step OAuth onboarding (open GCP → poll Downloads → smoke test → register account). Reduces first-run friction by ~80%.
  • gmail-cleanup autopilot --all-accounts — runs the full pipeline across every configured account with partial-failure semantics.
  • gmail-cleanup status — inbox health dashboard: live counts, filter inventory, list sizes, 7-day history.
  • gmail-cleanup attachments — storage cleanup. Finds oversized old emails, ranks senders by bytes attributed.
  • gmail-cleanup schedule install — daily launchd-scheduled autopilot (macOS).
  • gmail-cleanup config / accounts — manage ~/.gmail_cli/config.yaml. --email becomes optional once configured.
  • Rich progress UI + global --quiet (cron-safe) and --verbose (debug) flags.
  • Auto-close-the-loop on unsubscribes — successful unsubs auto-append to lists/unsubbed.yaml.

Under the hood

  • Package refactor: gmail_cli.py → gmail_cleanup/ package (7 modules, kept the same console-script entry).
  • Per-account state file at ~/.gmail_cli/state_<email>.json with 30-entry capped history.
  • New CI workflow runs pytest on Python 3.11/3.12/3.13 for every PR.

Tests

84 passing (was 52 at v0.4.0). +32 new tests covering config, accounts, state, atomic writes, attachments size parser, multi-account dispatch.

Install

```bash
pip install git+https://github.com/bgorzelic/gmail-cleanup.git
gmail-cleanup setup # first-time wizard
gmail-cleanup autopilot # daily cleanup
```

Full changelog: CHANGELOG.md
Architecture tour: ARCHITECTURE.md

v0.4.0 — autopilot + mark-read

Choose a tag to compare

@bgorzelic bgorzelic released this 16 May 07:45

The "Swiss army knife with an autopilot button" release.

  • gmail-cleanup autopilot — runs filters → unsubscribe → mark-read → verify in one shot. Idempotent, safe to run repeatedly.
  • gmail-cleanup mark-read — bulk-mark by query. Cleared 4,710 archived-unreads on the maintainer's account in one shot.
  • Filter upgrades now also remove UNREAD so categorized mail counts toward read.
  • Kill list additions: skool.com, invitations@linkedin.com, noreply@discord.com.

Full notes: CHANGELOG.md

v0.3.1 — credential search UX fix

Choose a tag to compare

@bgorzelic bgorzelic released this 16 May 07:45

Clean-room install audit found that the missing-credentials error said "place credentials.json in project dir" — meaningless when pip-installed (resolves inside site-packages). Fixed to search 4 locations in precedence order and print all checked paths + the GCP console URL.

Full notes: CHANGELOG.md

v0.3.0 — buttoned-up release

Choose a tag to compare

@bgorzelic bgorzelic released this 16 May 07:45

Repo turns from a working script into a productizable tool. Lists move to YAML, test suite lands (46 tests), verify subcommand audits stickiness, block-filter escalation, packaging as gmail-cleanup console script, CONTRIBUTING + CODE_OF_CONDUCT shipped.

Full notes: CHANGELOG.md

v0.2.0 — filters and verification

Choose a tag to compare

@bgorzelic bgorzelic released this 16 May 07:45

Declarative Gmail filter management via filters apply. Two-step approach: upgrades existing label-only filters with archive action, then creates the standard preset (human whitelist, has:list catch-all, previously-unsubscribed, killlist). Verification of 2026-05-14 unsubscribe cohort: 90% stickiness.

Full notes: CHANGELOG.md