9 Commits

Author SHA1 Message Date
vasyansk a2234077df feat: stream the metadata scan instead of Collect
CopyFolder now streams envelope metadata via Next() in a first pass (dedup +
queue new messages), then streams bodies for new ones in a second pass —
no more blocking Collect of the whole folder with zero feedback, and memory
stays flat (only new-message meta is held).

- imapx: two-pass streaming CopyFolder + CopyDeps.OnScan(scanned,total)
- orchestrator: throttled 'scan' events during the metadata pass
- web: per-account 'scanning folder: X/N' line under the progress bar;
  scan events kept out of the log to avoid flooding

Verified on greenmail: idempotency and internal-date preservation still hold.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMHQTtnQtQqL8muAXHr9kd
2026-07-02 13:35:08 +07:00
vasyansk 4959173f39 feat: planning pass counts all folders up front for account-wide progress
Before copying, EXAMINE every folder to sum the account's total message count
and emit a 'plan' event; progress events now carry account_total so the UI
shows a real overall bar, percent and ETA (not just per-folder).

- imapx.FolderMessageCount: read-only count of a folder
- orchestrator: plan pass + grandTotal, plan event, account_total in progress
- web: live progress keyed on account total; PLAN log line; overall bar/ETA

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMHQTtnQtQqL8muAXHr9kd
2026-07-02 13:21:57 +07:00
vasyansk f024f329fc feat: per-account cancel + folder message-count progress in log
- orchestrator: per-account cancellable context registry + CancelAccount;
  on cancel, close IMAP connections to unblock in-flight FETCH; account ends
  in 'cancelled' status with a cancelled event
- imapx: CopyDeps.OnFolder callback fires after EXAMINE with the folder's
  message count (before the long fetch) for visibility
- httpapi: POST /tasks/{id}/accounts/{accountId}/cancel
- web: per-row cancel button while running, folder event shows N messages,
  cancelled/done_with_errors status badges

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMHQTtnQtQqL8muAXHr9kd
2026-07-02 12:47:07 +07:00
vasyansk 2def11a870 fix(orchestrator): reuse src connection to list folders instead of extra TestLogin 2026-07-01 18:10:52 +07:00
vasyansk a54ec1d148 fix(imapx): preserve source internal date on APPEND 2026-07-01 17:57:12 +07:00
vasyansk 06c0598b80 feat(imapx): streaming per-folder copy with dedup, idempotent 2026-07-01 17:39:43 +07:00
vasyansk 79f5c5b93a fix(imapx): honor context in Connect with bounded dial retry 2026-07-01 17:28:10 +07:00
vasyansk 0451b79c64 feat(imapx): connect, endpoint test, login test with folder listing 2026-07-01 17:20:03 +07:00
vasyansk 37cb8ba076 feat(imapx): message dedup key (Message-ID + header fallback) 2026-07-01 17:03:18 +07:00