diff --git a/CHANGELOG.md b/CHANGELOG.md index ba8d4fb42..1830fd448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 ...`** — 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 ` 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 ...`) 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 [FOLDER]` / `em flag # 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 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index a3651f30d..e55e948f2 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -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 ...`** — 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 ` 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 ...`) 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 [FOLDER]` / `em flag # 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 diff --git a/docs/guides/EMAIL-COOKBOOK.md b/docs/guides/EMAIL-COOKBOOK.md index 25559c835..5d0f30b90 100644 --- a/docs/guides/EMAIL-COOKBOOK.md +++ b/docs/guides/EMAIL-COOKBOOK.md @@ -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 ``` @@ -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" diff --git a/docs/guides/EMAIL-DISPATCHER-GUIDE.md b/docs/guides/EMAIL-DISPATCHER-GUIDE.md index 9b7486e83..0ce90594c 100644 --- a/docs/guides/EMAIL-DISPATCHER-GUIDE.md +++ b/docs/guides/EMAIL-DISPATCHER-GUIDE.md @@ -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 @@ -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 @@ -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: @@ -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) @@ -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 diff --git a/docs/help/QUICK-REFERENCE.md b/docs/help/QUICK-REFERENCE.md index ef470b3be..7cbab33ff 100644 --- a/docs/help/QUICK-REFERENCE.md +++ b/docs/help/QUICK-REFERENCE.md @@ -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 @@ -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 diff --git a/docs/reference/MASTER-DISPATCHER-GUIDE.md b/docs/reference/MASTER-DISPATCHER-GUIDE.md index 380404fd7..0c5b690a8 100644 --- a/docs/reference/MASTER-DISPATCHER-GUIDE.md +++ b/docs/reference/MASTER-DISPATCHER-GUIDE.md @@ -3300,10 +3300,11 @@ calendar ICS parsing, and IMAP IDLE background watching. | `em delete --purge ` | | Permanent delete (requires typing "yes") | | `em create-folder ` | `em cf` | Create a new mail folder | | `em delete-folder ` | `em df` | Delete folder (type-to-confirm) | -| `em move [FOLDER]` | `em mv` | Move email to folder (fzf picker if no folder) | +| `em move ...` | `em mv` | Move email(s) to folder (`--pick` for fzf, `--recent` for last 3) | | `em restore ` | | Restore from Trash to INBOX | | `em flag ...` | `em fl` | One-way: set starred (batch-capable) | | `em unflag ...` | | 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 ` | | AI category classification | | `em summarize ` | `em sum` | One-line AI summary | @@ -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 diff --git a/docs/reference/REFCARD-EMAIL-DISPATCHER.md b/docs/reference/REFCARD-EMAIL-DISPATCHER.md index 1bcc6f0f1..02225f9d3 100644 --- a/docs/reference/REFCARD-EMAIL-DISPATCHER.md +++ b/docs/reference/REFCARD-EMAIL-DISPATCHER.md @@ -86,9 +86,8 @@ mindmap | **em summarize** | `sum` | `em summarize ` | One-line summary (AI) | | **em ai** | — | `em ai [claude\|gemini\|none\|auto\|toggle]` | Runtime AI backend switching | | **em catch** | `c` | `em catch ` | Capture email as task (AI summary → catch) | -| **em star** | `flag` | `em star ` | Toggle starred (Flagged) status | +| **em star** | — | `em star ...` | Toggle starred (Flagged) status, multi-ID | | **em starred** | — | `em starred [FOLDER]` | List starred emails | -| **em move** | `mv` | `em move [FOLDER]` | Move to folder (fzf picker if no folder) | | **em thread** | `th` | `em thread ` | Show conversation thread | | **em snooze** | `snz` | `em snooze