Skip to content

feat(fast-actions): one-click Email→Note/Task/Event/Contact (ODIAA-2333) - #33

Merged
amirhmoradi merged 1 commit into
mainfrom
odiaa-2333-fast-actions
Sep 28, 2026
Merged

amirhmoradi merged 1 commit into
mainfrom
odiaa-2333-fast-actions

Conversation

@amirhmoradi

Copy link
Copy Markdown
Contributor

Summary

  • Composite MCP tools + CLI commands email_to_note/email-to-note, email_to_task/email-to-task (uses action-item extraction), email_to_event/email-to-event (new deterministic, no-LLM date/time/location parser — extension/src/email-event-parse.js — falls back to a tentative draft event when nothing is detected), email_to_contact/email-to-contact (sender → contact, deduped by email).
  • Extension menus entries on the message list/display ("Save to Notes", "Create Task", "Create Event", "Add Sender to Contacts") route through the same handleRequest() used by the bridge, so a menu click gets identical access enforcement to the CLI/MCP path — no new bypass.
  • "Save to Notes" can't write to disk from the WebExtension sandbox, so it pushes a note-save-requested event over the bridge's existing /bridge/events long-poll feed; tb notes listen / MCP notes_listen_once is the CLI-side listener that turns the push into a saved note.
  • Two new ungated routes (GET /addressbooks, POST /messages/:id/event-draft) classified in extension/src/access-control.js. No new write switch: writes are gated by the existing tasksWrite/calendarWrite/contactsWrite switches, all still default-off.
  • Docs updated for surface parity: docs/ACCESS-CONTROL.md, docs/COMMANDS.md, README.md, SPEC.md, skills/thunderbird-cli/SKILL.md, CHANGELOG.md.

Test plan

  • npm test (66/66)
  • node test/access-control.test.mjs (92/92)
  • node test/mcp-test.mjs (73/73, tool count 31 → 37)
  • node test/email-event-parse.test.mjs (new, 26/26)
  • node test/notes-test.mjs / node test/action-items.test.mjs regression (72/72, 29/29)
  • node test/docs.test.mjs (99/99)
  • npm run lint (addons-linter clean)
  • npm run build:xpi (manifest builds with new menus/notifications permissions and the new background script)
  • npm run test:all (full suite, 0 failures)
  • Manual QA in a running Thunderbird instance (no browser capability in this environment) — reproducible plan: install the built XPI, enable tasksWrite/calendarWrite/contactsWrite in access.local.json, right-click a message in the list (and in the open message view) and confirm all four context-menu items appear and each produces the expected task/event/contact/notes-push, including the disabled-by-policy notification when a switch is off.

🤖 Generated with Claude Code

Composite MCP tools + CLI + extension context-menu items that compose
existing routes without a new access switch:

- email_to_note / tb email-to-note — save a message to the local notes
  workspace (no switch, notes are local-only).
- email_to_task / tb email-to-task — deterministic action-item extraction
  feeds a new task (requires tasksWrite).
- email_to_event / tb email-to-event — new deterministic (no LLM)
  date/time/location parser (extension/src/email-event-parse.js) feeds a
  new calendar event, falling back to a tentative draft when nothing is
  detected (requires calendarWrite).
- email_to_contact / tb email-to-contact — sender becomes a contact,
  deduped by email address (requires contactsWrite).
- address_book_list / tb address-books, and two new ungated routes
  (GET /addressbooks, POST /messages/:id/event-draft) classified in
  access-control.js.
- Extension menus on the message list/display ("Save to Notes", "Create
  Task", "Create Event", "Add Sender to Contacts") call the same
  handleRequest() router as the bridge, so a menu click enforces access
  identically to the CLI/MCP path.
- "Save to Notes" can't write to disk from the WebExtension sandbox, so it
  pushes a note-save-requested event over the bridge's existing long-poll
  feed; tb notes listen / notes_listen_once is the CLI-side listener.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@amirhmoradi
amirhmoradi merged commit 05eb7f1 into main Sep 28, 2026
2 checks passed
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