Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- **`em undo`** — single-step undo of the last `em star`/`flag`/`unflag`/`move` action (1-hour window, no multi-level undo stack). Uses `lib/em-cache.zsh`'s existing cache API.
- **`em move --recent <ID>...`** — quick-pick the target folder from the last 3 move destinations, no `fzf` required.
- **Centralized `ALIASES` section in `em help`** — single-source list of all short-form command aliases, instead of scattered per-command mentions.

### Fixed

- **`em move` was broken in production** — `_em_move` and its adapter `_em_hml_move` were each defined twice in the same file (zsh's last-definition-wins semantics), and the two live (later) definitions were incompatible with each other: the live `_em_move` called `_em_hml_move` with a numeric message ID in the source-folder position. Every `em move <ID> <folder>` call would attempt to move a message from a non-existent folder named after the ID. Removed the dead pair, kept the multi-ID interface (`em move <FOLDER> <ID>...`) that matches `em move --help`, `MASTER-DISPATCHER-GUIDE.md`, and the existing (previously unregistered) `tests/test-em-move-restore.zsh`. That test file — which would have caught this — was never wired into `tests/run-all.sh`; it is now.
- Corrected a dozen-plus stale `em move <ID> [FOLDER]` / `em flag <ID> # Alias for em star` references across `docs/help/QUICK-REFERENCE.md`, `docs/reference/MASTER-DISPATCHER-GUIDE.md`, `docs/reference/REFCARD-EMAIL-DISPATCHER.md` (which had both a stale and a correct `em move` row), `docs/guides/EMAIL-DISPATCHER-GUIDE.md`, `docs/guides/EMAIL-COOKBOOK.md`, and `man/man1/em.1` — all inherited the same wrong interface the code bug had.

## [7.16.0] — 2026-07-07 — agy em-ai backend + em ADHD-UX fixes

### Added
Expand Down
11 changes: 11 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ The format follows [Keep a Changelog](https://keepachangelog.com/), and this pro

## [Unreleased]

### Added

- **`em undo`** — single-step undo of the last `em star`/`flag`/`unflag`/`move` action (1-hour window, no multi-level undo stack). Uses `lib/em-cache.zsh`'s existing cache API.
- **`em move --recent <ID>...`** — quick-pick the target folder from the last 3 move destinations, no `fzf` required.
- **Centralized `ALIASES` section in `em help`** — single-source list of all short-form command aliases, instead of scattered per-command mentions.

### Fixed

- **`em move` was broken in production** — `_em_move` and its adapter `_em_hml_move` were each defined twice in the same file (zsh's last-definition-wins semantics), and the two live (later) definitions were incompatible with each other: the live `_em_move` called `_em_hml_move` with a numeric message ID in the source-folder position. Every `em move <ID> <folder>` call would attempt to move a message from a non-existent folder named after the ID. Removed the dead pair, kept the multi-ID interface (`em move <FOLDER> <ID>...`) that matches `em move --help`, `MASTER-DISPATCHER-GUIDE.md`, and the existing (previously unregistered) `tests/test-em-move-restore.zsh`. That test file — which would have caught this — was never wired into `tests/run-all.sh`; it is now.
- Corrected a dozen-plus stale `em move <ID> [FOLDER]` / `em flag <ID> # Alias for em star` references across `docs/help/QUICK-REFERENCE.md`, `docs/reference/MASTER-DISPATCHER-GUIDE.md`, `docs/reference/REFCARD-EMAIL-DISPATCHER.md` (which had both a stale and a correct `em move` row), `docs/guides/EMAIL-DISPATCHER-GUIDE.md`, `docs/guides/EMAIL-COOKBOOK.md`, and `man/man1/em.1` — all inherited the same wrong interface the code bug had.

## [7.16.0] — 2026-07-07 — agy em-ai backend + em ADHD-UX fixes

### Added
Expand Down
13 changes: 7 additions & 6 deletions docs/guides/EMAIL-COOKBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ em read --md 87 # Clean Markdown rendering (better for Outlook emails)

# Now act on it
em reply 87 # AI-drafted reply
em move 87 Archive # File it away
em move Archive 87 # File it away
em delete 87 # Move to Trash (y/N confirm)
em snooze 87 monday # Come back to it Monday 9am
```
Expand Down Expand Up @@ -200,12 +200,13 @@ em folders
# Create a new folder
em create-folder "Research 2026"

# Move emails into it (one at a time or batch)
em move 101 "Research 2026"
em mv "Research 2026" 102 103 104 # batch move: folder first, then IDs
# Move emails into it (folder first, then ID(s))
em move "Research 2026" 101
em mv "Research 2026" 102 103 104 # batch move

# Or move with fzf folder picker (no folder arg = interactive)
em move 105
# Or pick the target folder interactively
em move --pick 105 # fzf picker
em move --recent 105 # quick-pick from last 3 destinations

# List and clean up an old folder
em inbox 50 "Old Archive"
Expand Down
43 changes: 32 additions & 11 deletions docs/guides/EMAIL-DISPATCHER-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ em read 42 # Smart rendering (HTML/markdown/plain)
em reply 42 # AI draft in $EDITOR
em respond # Batch AI drafts for actionable emails
em star 42 # Toggle star/flag
em move 42 Archive # Move to folder
em move Archive 42 # Move to folder
em thread 42 # Conversation thread view
em snooze 42 2h # Snooze for later
em digest # AI-grouped daily summary
Expand Down Expand Up @@ -1225,9 +1225,11 @@ Toggle the IMAP `Flagged` flag on an email:

```bash
em star 42 # Toggle star on email #42
em flag 42 # Alias for em star
```

`em flag`/`em unflag` are separate one-way commands (set/clear only, batch-capable) —
not aliases of `em star`. See the Flag / Unflag section below.

**Output:**

```text
Expand Down Expand Up @@ -1261,22 +1263,36 @@ em starred — flagged emails
Move an email to a different folder:

```bash
em move 42 Archive # Move to Archive (with confirmation)
em move 42 # fzf folder picker (requires fzf)
em mv 42 Trash # Alias
em move Archive 42 # Move email #42 to Archive
em mv Trash 42 # Alias
em move Archive 10 20 30 # Batch move (multi-ID)
em move --from Sent Archive 42 # Move from a non-default source folder
em move --pick 42 # fzf folder picker
em move --recent 42 # Quick-pick from the last 3 destination folders
```

**With explicit folder:**
**Output:**

```text
Move #42 → Archive? [y/N] y
✅ Moved #42 to Archive
✅ Moved 1 email(s) to Archive
```

**Without folder (fzf picker):**
**`--pick` (fzf folder picker):**

Opens an interactive folder picker. Select a folder with Enter, or press Escape to cancel.

**`--recent` (quick-pick, no fzf required):**

```text
Recent folders:
1) Archive
2) Projects
3) Newsletter
Select [1-3]: 1
```

Undo a move (or star/flag/unflag) with `em undo` — one step, 1-hour window.

### Thread

View the conversation thread for an email — finds related messages by `References` / `In-Reply-To` headers and displays them chronologically:
Expand Down Expand Up @@ -1528,8 +1544,6 @@ Archive
### Delete Emails

```bash
em move 42 Archive # Move email to Archive (with confirmation)
em move 42 # Move with fzf folder picker
em inbox Sent # List sent emails
em pick Archive # Browse archive folder
# Delete by ID (moves to Trash)
Expand Down Expand Up @@ -1585,6 +1599,13 @@ em mv Archive 10 20 30 # Batch move

# Move from specific source folder
em move --from Sent Archive 42 # Sent → Archive

# fzf folder picker / recent-folders quick-pick
em move --pick 42 # fzf picker
em move --recent 42 # Pick from last 3 destinations

# Undo the last star/flag/unflag/move (one step, 1hr window)
em undo
```

### Restore from Trash
Expand Down
8 changes: 6 additions & 2 deletions docs/help/QUICK-REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1224,8 +1224,9 @@ em star 42 # Toggle star (Flagged) on email
em starred # List all starred emails

# Move to folder
em move 42 Archive # Move with explicit folder
em move 42 # Move with fzf folder picker (requires fzf)
em move Archive 42 # Move with explicit folder
em move --pick 42 # Move with fzf folder picker (requires fzf)
em move --recent 42 # Quick-pick from last 3 destinations

# Conversation thread
em thread 42 # Show chronological thread for email
Expand Down Expand Up @@ -1304,6 +1305,9 @@ em flag 42 # Star/flag email
em fl 42 43 # Batch flag
em unflag 42 # Remove star

# Undo the last star/flag/unflag/move (one step, 1hr window)
em undo

# AI extraction
em todo 42 # Extract action items → Reminders.app
em event 42 # Extract calendar events → Calendar.app
Expand Down
5 changes: 3 additions & 2 deletions docs/reference/MASTER-DISPATCHER-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3300,10 +3300,11 @@ calendar ICS parsing, and IMAP IDLE background watching.
| `em delete --purge <ID>` | | Permanent delete (requires typing "yes") |
| `em create-folder <name>` | `em cf` | Create a new mail folder |
| `em delete-folder <name>` | `em df` | Delete folder (type-to-confirm) |
| `em move <ID> [FOLDER]` | `em mv` | Move email to folder (fzf picker if no folder) |
| `em move <FOLDER> <ID>...` | `em mv` | Move email(s) to folder (`--pick` for fzf, `--recent` for last 3) |
| `em restore <ID>` | | Restore from Trash to INBOX |
| `em flag <ID>...` | `em fl` | One-way: set starred (batch-capable) |
| `em unflag <ID>...` | | One-way: clear starred (batch-capable) |
| `em undo` | | Undo last star/flag/unflag/move (1-step, 1hr window) |
| `em respond` | `em resp` | Batch AI drafts for actionable emails |
| `em classify <ID>` | | AI category classification |
| `em summarize <ID>` | `em sum` | One-line AI summary |
Expand Down Expand Up @@ -3344,7 +3345,7 @@ em forward 42 user@example.com --prompt 'FYI re: our discussion'
em reply 42 --backend agy # Override AI backend per-command
em respond # Batch process actionable emails
em star 42 # Toggle star on email
em move 42 Archive # Move email to folder
em move Archive 42 # Move email to folder
em thread 42 # Show conversation thread
em snooze 42 2h # Snooze for 2 hours
em digest # AI-grouped daily summary
Expand Down
11 changes: 6 additions & 5 deletions docs/reference/REFCARD-EMAIL-DISPATCHER.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,8 @@ mindmap
| **em summarize** | `sum` | `em summarize <ID>` | One-line summary (AI) |
| **em ai** | — | `em ai [claude\|gemini\|none\|auto\|toggle]` | Runtime AI backend switching |
| **em catch** | `c` | `em catch <ID>` | Capture email as task (AI summary → catch) |
| **em star** | `flag` | `em star <ID>` | Toggle starred (Flagged) status |
| **em star** | | `em star <ID>...` | Toggle starred (Flagged) status, multi-ID |
| **em starred** | — | `em starred [FOLDER]` | List starred emails |
| **em move** | `mv` | `em move <ID> [FOLDER]` | Move to folder (fzf picker if no folder) |
| **em thread** | `th` | `em thread <ID>` | Show conversation thread |
| **em snooze** | `snz` | `em snooze <ID> <TIME>` | Snooze email (2h, 1d, tomorrow, monday) |
| **em snoozed** | — | `em snoozed` | List snoozed emails with status |
Expand All @@ -108,10 +107,11 @@ mindmap
| **em delete** | `del, rm` | `em delete <ID> [--folder F] [--query Q] [--pick] [--purge]` | Delete email(s) — move to Trash (or permanent with --purge) |
| **em create-folder** | `cf` | `em create-folder <name>` | Create a new mail folder |
| **em delete-folder** | `df` | `em delete-folder <name>` | Delete folder (type-to-confirm) |
| **em move** | `mv` | `em move <FOLDER> <ID> [--from F]` | Move email(s) to folder |
| **em move** | `mv` | `em move <FOLDER> <ID>... [--from F\|--pick\|--recent]` | Move email(s) to folder |
| **em restore** | — | `em restore <ID> [--to F]` | Restore from Trash (default: to INBOX) |
| **em flag** | `fl` | `em flag <ID> [<ID>...]` | Star/flag email(s) |
| **em unflag** | — | `em unflag <ID> [<ID>...]` | Unstar/unflag email(s) |
| **em undo** | — | `em undo` | Undo last star/flag/unflag/move (1-step, 1hr window) |
| **em todo** | `td` | `em todo <ID> [<ID>...]` | Extract action items (AI) → Reminders.app |
| **em event** | `ev` | `em event <ID> [<ID>...]` | Extract calendar events (AI) → Calendar.app |

Expand Down Expand Up @@ -531,8 +531,6 @@ em catch 42 # AI summarize → pipe to catch
# Organizing
em star 42 # Toggle star (flagged)
em starred # List starred emails
em move 42 Archive # Move to Archive
em move 42 # fzf folder picker
em thread 42 # Show conversation thread
em snooze 42 2h # Snooze for 2 hours
em snooze 42 tomorrow # Snooze until tomorrow 9am
Expand All @@ -547,9 +545,12 @@ em delete --query "newsletter" # Delete by search
em delete --purge 42 # PERMANENT delete (requires "yes")
em move Archive 42 # Move to Archive
em mv Archive 10 20 30 # Batch move
em move --pick 42 # fzf folder picker
em move --recent 42 # Quick-pick from last 3 destinations
em restore 42 # Restore from Trash → INBOX
em flag 42 # Star/flag email
em unflag 42 # Remove star
em undo # Undo the last star/flag/unflag/move
em todo 42 # AI → extract action items
em event 42 # AI → extract calendar events

Expand Down
Loading