# Sho'Nuff Inbox Monitoring

Goal: Monitor `shonuff@germainebrown.com` for incoming replies/emails, extract content, and notify Germaine via Telegram.

## Architecture

Two-layer system:

1. **Collector script** (`shonuff-inbox-collect.py`, `no_agent=True`) — runs every 15m, checks for UNSEEN messages from non-trusted senders, outputs JSON with: from, subject, date, body_preview (first 500 chars), uid. Silent when nothing new. Marks messages as Seen after processing.

2. **LLM cron job** — takes the collector's JSON output, summarizes each message in 2-3 sentences for Germaine: who sent it, what it's about, whether action is needed. Responds with SILENT when nothing new.

## Script location

`/root/.hermes/scripts/shonuff-inbox-collect.py`

## Trusted senders (skipped, not reported)

```python
TRUSTED = ["g@germainebrown.com"]
```

The collector skips messages FROM these addresses entirely — no output, no summary. All other senders are reported.

## Known limitations

- **Apple Mail replies are HTML-only** — they often send with no `text/plain` alternative. The `get_text_body()` function strips HTML tags to extract plain text, but this can miss content that's rendered only through CSS or loaded images.
- **Body preview is truncated at 500 chars** — the LLM summary may need more context for long messages. The preview in the JSON output is an excerpt, not the full body.

## Body extraction

```python
def get_text_body(msg):
    body = ""
    if msg.is_multipart():
        for part in msg.walk():
            ct = part.get_content_type()
            if ct == "text/plain":
                payload = part.get_payload(decode=True)
                if payload:
                    body += payload.decode("utf-8", errors="replace")
    else:
        payload = msg.get_payload(decode=True)
        if payload:
            body = payload.decode("utf-8", errors="replace")
    body = re.sub(r'\s+', ' ', body).strip()
    return body[:2000]
```

The fallback path (HTML-only) is handled by extracting `text/html` parts and stripping tags manually.

## Cron config

- Schedule: `every 15m`
- `no_agent=True` on the collector
- LLM cron reads output via `context_from` job ID
- If nothing changed from last run, the LLM responds SILENT and the user sees nothing

## Setup checklist

- [x] IMAP credentials in `.env` (`SHONUFF_EMAIL`, `SHONUFF_EMAIL_PASS`)
- [x] Collector script at `~/scripts/shonuff-inbox-collect.py`
- [x] `no_agent=True` cron at 15m
- [x] LLM cron reading collector's output
- [x] Trusted senders configured
- [x] Base64 image for signature stored at `~/references/shonuff-image-b64.txt`
