feat(watcher): add agent Gmail CLI with audit and defaults
Provide list/read/summarize plus reason-gated archive, label, draft, and forward-as-draft, with SQLite audit logging and default-mailbox resolution. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
# Usage — agent Gmail toolbox
|
||||
|
||||
How Cursor agents (and you) operate connected Gmail accounts via CLI. The web UI is a reader only.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Sign in via the web UI at least once **per** mailbox (`gmail.modify` scope — see [development.md](development.md#change-google-api-permissions-gmailmodify)).
|
||||
2. Set a default if more than one account is connected:
|
||||
|
||||
```bash
|
||||
npm run gmail -- accounts
|
||||
npm run gmail -- accounts --default you@gmail.com
|
||||
```
|
||||
|
||||
Optional env override: `GMAIL_DEFAULT_USER=you@gmail.com`.
|
||||
|
||||
## Account resolution
|
||||
|
||||
1. `--user <email|id>`
|
||||
2. `GMAIL_DEFAULT_USER`
|
||||
3. `users.is_default`
|
||||
4. Sole connected account
|
||||
5. Else error — set a default
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
npm run gmail -- <command> …
|
||||
```
|
||||
|
||||
| Command | Purpose | `--reason` |
|
||||
|---|---|---|
|
||||
| `accounts` | List mailboxes / set `--default` | no |
|
||||
| `list` | Search → id / from / subject | no |
|
||||
| `read <id>` | Full headers + body | no |
|
||||
| `summarize` | Compact digests for one or many (`--ids` or `--query`) | no |
|
||||
| `labels` | List label ids/names | no |
|
||||
| `label <ids> --add/--remove` | Modify labels | **required** |
|
||||
| `archive <ids>` | Remove `INBOX` | **required** |
|
||||
| `draft --to --subject --body` | Create a draft (**never sends**) | **required** |
|
||||
| `forward <id> --to [--note]` | Forward-as-draft | **required** |
|
||||
| `audit` | Show recent CLI audit rows | no |
|
||||
|
||||
Shared: `--user`, `--json`, `--dry-run` (mutations: no Gmail write; audit `status=dry-run`).
|
||||
|
||||
Aliases:
|
||||
|
||||
```bash
|
||||
npm run list-messages -- … # → gmail list
|
||||
npm run process-messages -- … # receipt backfill (see development.md)
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
npm run gmail -- list --query 'is:unread newer_than:3d' --max 40
|
||||
npm run gmail -- read 18c0… --json
|
||||
npm run gmail -- summarize --query 'in:inbox newer_than:7d' --max 15
|
||||
|
||||
npm run gmail -- label ABC,DEF --add receipts --reason "tag Grab receipts"
|
||||
npm run gmail -- archive ABC --reason "newsletter: Product Hunt daily"
|
||||
npm run gmail -- archive ABC --dry-run --reason "preview bulk archive"
|
||||
|
||||
npm run gmail -- draft \
|
||||
--to colleague@example.com \
|
||||
--subject "Re: Invoice" \
|
||||
--body "Thanks — I'll review today." \
|
||||
--reason "polite reply draft; user will send"
|
||||
|
||||
npm run gmail -- forward ABC \
|
||||
--to accounting@example.com \
|
||||
--note "Please book this receipt." \
|
||||
--reason "forward Grab receipt to accounting"
|
||||
|
||||
npm run gmail -- audit --limit 30
|
||||
npm run gmail -- audit --action archive --user you@gmail.com --json
|
||||
```
|
||||
|
||||
## Audit log
|
||||
|
||||
Every CLI action writes a row to SQLite `audit_log` (same `apps/api/data/app.db`):
|
||||
|
||||
- `actor` = `cli`
|
||||
- `action`, `mailbox`, `message_ids`, `payload` (JSON), `status` (`ok` | `error` | `dry-run`)
|
||||
- `reason` — required for mutations; optional elsewhere
|
||||
|
||||
Failures still write `status=error`. Receipt watcher success stays in PocketBase `spendings.parsed` + stdout; it is not mixed into this table.
|
||||
|
||||
## Safety
|
||||
|
||||
- Never call send. Never trash/delete.
|
||||
- Always pass a real `--reason` on mutations (explains intent in the audit log).
|
||||
- Ask the user before bulk archive (roughly >20 messages).
|
||||
- Prefer `--dry-run` when unsure.
|
||||
- Drafts stay in Gmail Drafts until the user sends them in the Gmail UI.
|
||||
|
||||
## Ideas — what agents can do
|
||||
|
||||
These are workflows on top of the CLI, not extra product features.
|
||||
|
||||
- **Inbox triage:** list unread → summarize a batch → archive newsletters after labeling.
|
||||
- **Receipt desk:** search provider subjects → `--add receipts` → `process-messages` into PocketBase.
|
||||
- **Draft, never send:** reply drafts, declines, “please re-send invoice” — you hit Send in Gmail.
|
||||
- **Forward-as-draft:** receipt or travel mail → draft to accounting/partner with `--note`.
|
||||
- **Label taxonomy:** `travel`, `bills`, `need-reply`, `waiting` — agents apply labels instead of inventing folders.
|
||||
- **Weekly digest:** `newer_than:7d is:unread` → summarize by sender → archive obvious noise.
|
||||
- **Follow-up queue:** find unanswered threads → draft a bump → leave in Drafts.
|
||||
- **Multi-mailbox:** omit `--user` for the default; pass `--user` for work vs personal.
|
||||
Reference in New Issue
Block a user