Releases: Xplore-LAB/postbird
Release list
v1.3.0 — archive, stats & cleanup advisor (lifecycle complete)
The receive side grows up: six new tools close out the archive, analyze, and clean segments of the mail lifecycle. The toolkit is now 14 tools covering all six segments — write, send, receive, archive, analyze, clean.
Added
office_archive_search— search the local JSONL index by sender, subject keyword, time window, attachment presence, or triage category. Works fully offline.office_archive_export— export matched messages as.eml+index.csv(the org-handover scenario: package a term of committee mail for the next committee). Sources are re-fetched read-only with BODY.PEEK; output is confined to workDir with deduped, sanitized filenames.office_archive_attach— batch-download attachments (the sign-up scenario: collect every résumé PDF from a public inbox). Per-attachment size cap (maxAttachmentMb), optional extension filter, path-escape blocked, skips always reported.office_stats_overview— monthly trend, top senders and recipients, category mix, and subscription share, computed locally from the index + send audit log. Zero network.office_stats_track— job-application ledger (求职台账): deterministic keyword signals auto-merge forward-only (applied → written-test → interview → offer; a rejected signal never overrides a recorded offer), freemail recruiting mail is returned asunattributedfor the agent to assign, manualupdateentries take precedence, andexportwrites a CSV thatoffice_sheetcan aggregate.office_inbox_clean— subscription cleanup advisor: a per-sender frequency table ranked by mail volume, the List-Unsubscribe URL surfaced when the sender provided one, and actionable advice per sender. Output-only — it never unsubscribes, deletes, moves, or sends anything.
Changed
office_inbox_fetchnow records the List-Unsubscribe URL in the index metadata (headers.listUnsubscribeUrl), feeding the advisor without re-fetching.- Config grows
maxArchiveMessages(default 200) andmaxAttachmentMb(default 25). - SECURITY.md documents the archive / stats / clean principles: write confinement, explicit caps, full-text-on-disk only by explicit export request, forward-only auto-merging, advice-only cleanup.
Under the hood
New modules lib/archive.js, lib/stats.js, lib/clean.js (all pure where possible: filter / aggregate / advise functions are exported and unit-tested). Tests grew from 71 to 100 — archive filters and guards, overview aggregation, ledger scan / dedup / forward-only / export, advisor thresholds and URL surfacing. DSH web-boot verified with all 14 tools loaded.
Full scenario map: docs/MAIL-SCENARIOS.zh-CN.md. Security model: SECURITY.md.
v1.2.0 — read-only inbox fetch & triage
The receive side of the mail lifecycle lands: two new tools close the inbox-triage loop.
Added
office_inbox_fetch— read-only IMAP pull of the newest messages (envelope, short body snippet, attachment list). Bodies are fetched with BODY.PEEK so \Seen is never set; no flags are written, nothing is deleted. Results are appended to a local JSONL index (~/.dsh/office/mail/index.jsonl, metadata only) with messageId dedup — the shared data layer for the upcoming archive and stats tools. Host presets for qq / foxmail / 163 / 126 / gmail / outlook / hotmail / live are auto-derived from the account address; other providers setimapHost. Credentials go through theDSH_IMAP_PASSenv var, never config files. QQ / 163 / 126 require an IMAP authorization code, not the login password.office_inbox_triage— deterministic classification of the fetched index into four buckets: todo (deadlines, interviews, offers, verification codes), notice (announcements, reminders, .edu.cn senders), subscription (bulk headers, no-reply senders, known bulk domains), personal (1:1 mail, replies). Every verdict carries its rule evidence; low/medium-confidence items are listed inneedsReviewfor semantic refinement by the agent. Also emitssubscriptionSenders, a per-sender frequency table that will feed the v1.5 unsubscribe advisor.
Security posture
IMAP is strictly read-only; local persistence is metadata plus a 300-character snippet (no full text, no attachment content); mail bodies are treated as untrusted input per SECURITY.md.
Under the hood
ImapFlow 1.4.1 + mailparser 3.7 (both Postal Systems, MIT — the same lineage as the existing nodemailer SMTP path). Tests grew from 46 to 71, including 25 inbox cases: provider presets, classification rules and their priority order, index dedup, and an isolated-office-home triage e2e.
Full scenario map and the v1.3-v1.5 roadmap (archive, stats, unsubscribe advisor): docs/MAIL-SCENARIOS.zh-CN.md.
v1.1.1 — security hardening
Security release. Three vulnerabilities fixed and disclosed, four guardrails added.
Fixed
- Attachment path escape (high): a crafted spreadsheet cell in an attachment column could attach arbitrary local files to outbound mail. Attachment paths are now confined to the working directory; escaping rows are blocked at preview time with an explicit problem message.
- pptx imagePath escape (high): same class of bug for images embedded into generated decks. Now confined to workDir.
- Mail header CRLF injection (medium): values rendered into Subject and To display names are stripped of CR/LF, so untrusted cells cannot forge headers such as Bcc.
Added guardrails
dailySendCap— rolling-24h delivered-message cap (default 200), enforced from the append-only audit logallowDomains— optional recipient-domain allowlist for organization-scoped sending- Duplicate-recipient detection within a batch
Tests grew from 37 to 46, including 9 dedicated security cases. Full threat model, vulnerability history, and reporting channel: see SECURITY.md.
v1.1.0 — pptx generation & docx template injection
Two new tools join the toolkit:
- office_pptx — generate .pptx decks from structured slide blocks (title / bullets / content / table / image) with {{field}} variables and batch mode (one deck per CSV/JSON row). Built on pptxgenjs 4.0.
- office_template — fill placeholders inside an existing .docx template, merging placeholders that Word split across formatting runs. Every placeholder must be provided or the call fails; batch mode renders one document per data row. Built on jszip.
Existing tools unchanged: office_mail_preview/send, office_docgen, office_sheet. 37 end-to-end checks passing.