Skip to content

fix(em): flag/star dead-case-label bug + help discoverability#493

Merged
Data-Wise merged 1 commit into
devfrom
feature/em-ux-refactor
Jul 7, 2026
Merged

fix(em): flag/star dead-case-label bug + help discoverability#493
Data-Wise merged 1 commit into
devfrom
feature/em-ux-refactor

Conversation

@Data-Wise

Copy link
Copy Markdown
Owner

Summary

Implements Phase 1+2 of docs/specs/SPEC-em-ux-refactor-2026-07-07.md, from this session's ADHD-UX audit of em.

P0 fix — dead-code bug: em()'s dispatch case statement had star|flag) bound to _em_star in the ORGANIZE section AND flag|fl) bound to _em_flag earlier in the MANAGE section. Since zsh case matches top-down, em flag always resolved to _em_flag (one-way add) and never reached _em_star's toggle logic — the flag alias on the star arm was unreachable dead code. Fixed so each command name maps to exactly one function; also removed a harmless duplicate move|mv) label. _em_star extended to accept multiple IDs (toggling each independently against one consistent folder snapshot) to match flag/unflag's existing batch capability.

Phase 2 — discoverability: added em help <topic> (inbox/compose/organize/manage/safety/ai/search) so users aren't stuck scanning a ~90-line dump for one thing; no-arg em help output is unchanged. Documented the existing 3-tier confirmation system ([y/N/e] / type "yes" / type folder name) in the SAFETY section as an intentional design. Updated MASTER-DISPATCHER-GUIDE.md and the man page, including fixing a duplicate em move reference row and a stale "em flag is an alias for em star" note that mirrored the same underlying bug.

Test plan

  • New tests/test-em-flag-star.zsh — 6/6 pass: routing regression (flag/star/unflag each hit a distinct function), multi-ID parity, and a grep-based dead-code guard.
  • Positive control on the guard test: reintroduced the exact original duplicate-label bug, confirmed the guard fails with word 'flag' bound to both '_em_flag' and '_em_star', restored the fix, confirmed 6/6 green again. (Note: the routing tests alone do NOT catch this bug — zsh's top-down case matching means em flag behaves identically whether or not the duplicate label is present. Only the dead-code guard specifically detects it, which is why it's its own dedicated test.)
  • Live verification: em flag 42 and em star 42 43 route to distinct mocked functions with correct args; em help organize, em help safety, em help badtopic (error path) all verified live.
  • ./tests/run-all.sh — 78 passed, 0 failed, 0 timeout, 1 skipped (expected — e2e-em-dispatcher skips when the external tool is absent, same baseline as before this PR, +1 for the new suite).
  • mkdocs build --strict — clean, run twice (before and after the man-page/CHANGELOG pass).
  • tests/test-manpage-version-sync.zsh — 12/12 clean.

🤖 Generated with Claude Code

…1+2)

Per SPEC-em-ux-refactor-2026-07-07.md, from this session's ADHD-UX audit
of em.

P0 fix: em()'s dispatch case statement had "star|flag)" bound to _em_star
in one section AND "flag|fl)" bound to _em_flag in another, earlier
section. Since zsh case matches top-down, `em flag` always resolved to
_em_flag (one-way add) and never reached _em_star's toggle logic --
the "flag" alias on the star arm was dead code. Fixed the routing so
each command name maps to exactly one function; also removed a harmless
duplicate `move|mv)` label. _em_star extended to accept multiple IDs
(toggling each independently against one consistent folder snapshot)
to match flag/unflag's existing batch capability.

Added tests/test-em-flag-star.zsh: routing regression tests (flag/star/
unflag each hit a distinct function), multi-ID parity tests, and a
grep-based dead-code guard that specifically detects the same case-label
word bound to two different handlers (not just any repeated word --
verified against a false positive on legitimate multi-word aliases).
Verified the guard actually catches this exact bug class via a planted-
defect positive control (reintroduced the old duplicate label, confirmed
the guard fails with the right message, restored the fix).

Phase 2: added `em help <topic>` (inbox/compose/organize/manage/safety/
ai/search) so users aren't stuck scanning a ~90-line dump for one thing;
no-arg `em help` output is unchanged. Documented the existing 3-tier
confirmation system ([y/N/e] / type "yes" / type folder name) in the
SAFETY section as an intentional design, not an incidental discovery.
Updated MASTER-DISPATCHER-GUIDE.md and the man page to match, including
fixing a duplicate `em move` reference row and a stale "em flag is an
alias for em star" note that mirrored the same underlying bug.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Data-Wise Data-Wise merged commit c1177a1 into dev Jul 7, 2026
2 checks passed
@Data-Wise Data-Wise deleted the feature/em-ux-refactor branch July 7, 2026 18:31
Data-Wise added a commit that referenced this pull request Jul 7, 2026
…dd em undo + recent-folders (Phase 3) (#497)

em move <ID> <folder> was broken in production: _em_move and its adapter
_em_hml_move were each defined twice in email-dispatcher.zsh/em-himalaya.zsh,
and zsh's last-definition-wins semantics meant the two LIVE definitions were
incompatible with each other — the live _em_move called _em_hml_move with the
numeric message ID in the source-folder position. Every move would attempt to
move a message from a folder named after its own ID.

Same failure class as the flag/star case-duplicate bug fixed earlier this
session (PR #493), this time a duplicate function definition rather than a
duplicate case label. Caught by tests/test-em-move-restore.zsh, which was
never wired into tests/run-all.sh (orphaned, like test-em-ai-switch.zsh was) —
it now fails 3/8 -> passes 8/8 against the fixed source and is registered.

Kept the multi-ID interface (em move <FOLDER> <ID>...) since it matches
em move --help, MASTER-DISPATCHER-GUIDE.md, and the orphaned test file.
Corrected the same stale <ID>-first interface across QUICK-REFERENCE.md,
MASTER-DISPATCHER-GUIDE.md, REFCARD-EMAIL-DISPATCHER.md (which had both a
stale and a correct em move row), EMAIL-DISPATCHER-GUIDE.md,
EMAIL-COOKBOOK.md, and man/man1/em.1 — plus a leftover "em flag = alias for
em star" line the Phase 1+2 docs sweep missed.

Phase 3 (docs/specs/SPEC-em-ux-refactor-2026-07-07.md):
- em undo: single-step undo of the last star/flag/unflag/move (1hr window,
  no stack), built on lib/em-cache.zsh's existing get/set API
- em move --recent <ID>...: quick-pick target folder from last 3
  destinations, no fzf required
- Centralized ALIASES section in em help (single source of truth instead of
  scattered per-command mentions)

Tests: tests/test-em-undo.zsh (16 new tests), tests/test-em-move-restore.zsh
(8/8, newly registered), tests/test-em-help-guards.zsh (undo help coverage).
Full suite: 80 passed, 0 failed, 1 skipped. mkdocs build --strict clean.
Man-page guard: 12/12.


Claude-Session: https://claude.ai/code/session_01JnVugoVjTHRK41krTTMi8L

Co-authored-by: Test User <test@example.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant