Mail, files, calendar and contacts for the ordner suite, from the shell — each protocol is a plugin

v2 commands: mail copy/mark/rm/draft/attachment, webdav copy/move/quota/share, calendar show/find/export/import #17

Merged emma.ordner.fyi
targeting main from v2-commands
Merged opened by and assigned to emma.ordner.fyi
targeting main from v2-commands

Implements every command that the v2 surface (bb692d7) added as a stub, across mail, webdav and calendar. It also fixes mail send --attach, which silently dropped the attachments.

Not yet run against a live server. Everything is tested against in-process fakes built from the suite's own source (ordner.fyi).

mail #

  • send --attach now works: each file is uploaded as a blob, and the email references it. Before, the files were read and then ignored.
  • send --draft <id> (new) sends a stored draft. The draft help already promised this, but no such option existed.
  • copy adds the message to one more mailbox, the same way the IMAP gateway's COPY works; the id does not change.
  • mark sets or clears only the read and flagged keywords you name.
  • rm moves the message to Trash, as the webmail does. --destroy deletes it for good.
  • draft stores a message in Drafts, attachments included.
  • attachment downloads one part, chosen by part id or file name.

webdav #

  • copy/cp, move/mv: done by the server. An existing target is never replaced without --force; copy --shallow copies a folder without its contents.
  • quota reads RFC 4331 used/available.
  • share <folder> --to <id> [--access read|read-write|upload-only], unshare: sharing goes through the WebDAV ACL method, which a webdav-scoped app password may use. Other grants on the folder are kept, and protected grants are never sent back. share prints the share link.

calendar #

  • show <id> [--occurrence <rid>] shows a whole event or a single occurrence.
  • find <text> uses the server's text filter, which matches titles only.
  • export writes one VCALENDAR in the shape of the suite's export. The VTIMEZONEs are generated from Temporal's IANA data and tested against IANA offsets up to 2045.
  • import:
    • groups a master and its RECURRENCE-ID instances into one event;
    • maps Windows/Mozilla zone names to IANA;
    • skips UIDs the account already holds, so a re-import is a no-op; --update replaces them where they live instead.

Changes to what bb692d7 declared #

  • mail rm: the default is now Trash (the stub destroyed and needed --yes).
  • mail copy: returns the original id.
  • mail mark: --read --unread together is a usage error.
  • calendar find: matches titles only, not description and location.
  • calendar --tz: replaces the hard-coded Europe/Vienna.
  • --account: every new command takes it now; the stubs ignored it.
  • Duplicate --json: the per-command --json declarations are removed, since --json is global.
  • -a: --attach had taken -a, which --account owns.
  • Port types: they grew to return what the commands report (see protocols/types.ts).

A new test walks the command tree and fails if one short flag is given to two options.

Checks #

  • npm run typecheck, npm test (122, up from 88), npm run pack, npm run smoke: all pass.
  • Tests and smoke run under the loopback-only network guard.

Not verified against a real server #

  • mail: whether an imap-scoped app password may upload; whether a stored draft comes back with its bcc.
  • webdav: whether the proxy passes the ACL method through and keeps the COPY/MOVE Destination host; the exact share-link URL. Also, share reads and then writes with no precondition, so a concurrent edit in the web app could be lost.
  • calendar: how the uid lookup behaves across calendars; how real clients read the generated VTIMEZONEs; large imports against the aggregator's timeout.
Commits 0