Metadata-Version: 2.4
Name: navig-email
Version: 0.3.0
Summary: Gmail mailroom: rules, watch, labels, stats, digests, drafts — its own navig-email command (Gmail app password over IMAP), and `navig email` inside navig.
Author-email: NAVIG Development Team <opensource@navig.run>
License-Expression: Apache-2.0
Project-URL: Homepage, https://navig.run
Project-URL: Documentation, https://navig.run/docs
Keywords: navig,cli,agent,automation,plugin,email,imap,smtp,inbox
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: navig-sdk>=2.11.0
Requires-Dist: navig-vault>=0.7.0
Requires-Dist: typer>=0.14.0
Requires-Dist: rich>=13.7.0
Requires-Dist: pyyaml>=6.0
Dynamic: license-file

# navig-email

<!-- navig:plugin-card:start -->
<!-- Generated by scripts/gen_plugin_catalog.py — edit the plugin's pyproject.toml, not this block. -->

> Gmail mailroom: rules, watch, labels, stats, digests, drafts — its own navig-email command (Gmail app password over IMAP), and `navig email` inside navig.

**Works on its own** — its own CLI, no navig required · v0.3.0 · [PyPI](https://pypi.org/project/navig-email/)

**On its own** (no navig needed)

```bash
pip install navig-email
navig-email --help   # no navig needed
```

**With navig**

```bash
pip install navig-email
navig email --help
```

<details><summary>Commands</summary>

| Command | What it does |
|---|---|
| `navig email connect` | Link a Gmail account: OAuth inside navig, a Gmail app password on its own. |
| `navig email digest` | Template digest for the period; `--llm` adds prose through the guarded model door. |
| `navig email edge deploy` | Deploy the Worker from the plugin's edge/ folder (uses wrangler's own login). |
| `navig email edge events` | Recent messages the edge handled (metadata only — never bodies). |
| `navig email edge secrets` | Push the Worker's secrets from navig's own vault/config. Nothing is ever printed. |
| `navig email edge send` | Send AS support@<domain> (or another @domain address) through Cloudflare Email Sending. |
| `navig email edge stats` | Counts by alias / tag / day / sender domain for mail that entered at the edge. |
| `navig email edge status` | Is the Worker up, and does it have Email Sending? |
| `navig email followup` | Draft follow-ups in the space's style for ledger threads (opt-in model; drafts only). |
| `navig email imap connect` | Sign in to Gmail over IMAP with an app password, and keep it in the encrypted vault. |
| `navig email imap disconnect` | Forget the stored app password. |
| `navig email imap status` | Whether an app password is stored, and where it comes from (never shows it). |
| `navig email labels ensure` | Create a label (and its parents) if missing; print its id. |
| `navig email labels list` | Every label with its counts. |
| `navig email list` | List messages of a folder (newest first). |
| `navig email read` | Read one message (or its whole thread), body included. |
| `navig email replied` | Find every Sent reply to mail that sat in a folder (spam): ledger, corpus, label, stats. |
| `navig email rules apply` | Run the rules over existing mail (backfill labels). Notifications are NOT sent here. |
| `navig email rules check` | Validate the rules file; with a message id, show which rules would fire. |
| `navig email rules list` | The rules the watch applies (space file + enabled daemon rules). |
| `navig email search` | Search with Gmail's own syntax (spam and trash included). |
| `navig email send` | Send (or draft) a message — through Gmail, or AS the domain via the Cloudflare edge. |
| `navig email stats` | Counts for the period (received/sent/spam/unread, per label & rule, top senders, per day). |
| `navig email status` | Connected account, mailbox size, rules loaded, last watch. |
| `navig email tag` | Add/remove labels on one message or on a search result. |
| `navig email watch` | One incremental pass over new mail: rules → labels / Telegram / run. For cron (every 5 min). |

</details>

<!-- navig:plugin-card:end -->

NAVIG Email module — the Gmail side of a **mailroom**: list/search/read, labels, rules →
incremental watch (labels · Telegram · `run:`), stats, digests, a spam-reply ledger, and the
daemon's filter→notify triage + scheduled briefings. A first-party navig plugin (free, toggleable).

**License:** Apache-2.0 · **Version:** 0.2.0

## What it is

`navig-email` is a **first-party NAVIG plugin** — it extends NAVIG itself (CLI verbs +
gateway routes), and it is free and toggleable. It reads and writes Gmail through navig's
OAuth connector (`navig connector connect gmail`); it never carries credentials of its own.

**Local-first by design.** Tagging, watching, stats, digests, the replied-finder and every
Telegram line are pure logic. A language model is consulted only when a command says so
(`digest --llm`, `followup --draft`), the provider is printed, and a non-local provider is
refused unless `--allow-cloud` is passed.

## The mailroom (per space)

A space holds the operator-owned pieces:

```
<space>/mailroom/rules.yaml        rules: match {to, from, from_any, subject_any, body_words, in, has_attachment}
                                   actions: label:<Name> · notify:telegram · star · archive · mark_read · run:navig …
<space>/mailroom/ledger/*.jsonl    ledgers (e.g. piratebay.jsonl), idempotent by thread
<space>/mailroom/reports/*.md      stats / digest / ledger stats
<space>/.navig/email/state.json    the watch cursor (Gmail historyId) + seen ids
```

```
navig email status  [--space S]
navig email connect                             # = navig connector connect gmail
navig email list    [--folder inbox|spam|sent|all] [-q …] [-n]
navig email search  "<gmail query>" [-n] [--json]
navig email read    <id> [--thread]
navig email labels  list | ensure <Name>
navig email tag     (<id> | -q "<query>" --yes) --add <Name> [--remove <Name>]
navig email rules   list | check [<id>] | apply -q "<query>" --yes|--dry-run     --space S
navig email watch   --space S --yes|--dry-run                                   # cron, every 5 min
navig email stats   --space S --period day|week|month [--since --until] [--send]
navig email digest  --space S --period week|month [--llm --allow-cloud] [--send]
navig email send    --to … --subject … [--body …|stdin] [--reply-to <id>] --yes | --draft
navig email replied --space S --in spam --since YYYY-MM-DD [--ledger piratebay] [--label … --apply-labels] [--send]
navig email followup --space S --ledger piratebay --draft [--only-answered] [--model ollama:…] [--allow-cloud]
```

## The edge (Cloudflare Worker on the domain aliases)

`edge/` ships `cybesis-mailroom`, an Email Routing Worker: **forward first**, then one Telegram
line (per-alias policy, `NOTIFY_ALIASES`) and one metadata row in D1 — never the body — plus an
`X-Cybesis-Tag` header on the forwarded copy. Its bearer-protected API is what navig calls:

```
navig email edge status|stats [--days N --send]|events [-n N]      --space S
navig email edge send --to … --subject … --body … [--from legal@cybesis.com] --yes   # send AS the domain
navig email send --via cloudflare …                                 # same, from the generic verb
navig email edge deploy [--dry-run]                                 # wrangler deploy from edge/
```

Config: `mailroom.edge.url` in the space (`.navig/config.yaml`); vault label `mailroom/edge_token`
(= the Worker's `EDGE_TOKEN` secret). Worker secrets: `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`,
`EDGE_TOKEN`. Tests: `cd edge && node --test test/*.test.mjs`.

## Install

It ships in the NAVIG monorepo and loads automatically when NAVIG is installed.
To add/enable it explicitly:

```
navig plugin add navig-email
```

## Development

This package lives in the NAVIG monorepo under `plugins/navig-email/`. It registers via
the `navig.plugins` entry-point group; CLI verbs register via `navig.commands`.
Tests: `python -m pytest plugins/navig-email/tests` (an in-memory Gmail in `tests/fake_gmail.py`).
