import { demoCalendarInvitationEmails } from "@/lib/demo-calendar-invitation-emails" export type EmailAttachmentKind = "pdf" | "image" | "other" export interface EmailAttachment { name: string kind?: EmailAttachmentKind /** Taille en octets (optionnelle) — tooltips / pills vs cartes dans l’aperçu */ sizeBytes?: number /** Contenu texte inline (ex. ICS) — fixtures / import */ inlineText?: string } /** ICS ou métadonnées calendrier pour l’aperçu type Gmail */ export interface CalendarInvitationMeta { /** Texte ICS (text/calendar) */ ics?: string } export interface ConversationMessage { id: string sender: string senderEmail: string /** ISO 8601 avec fuseau (ex. `2026-05-16T01:38:00+02:00`) */ date: string body: string preview: string attachments?: EmailAttachment[] /** Lu / non lu du message (fixtures legacy). */ read?: boolean } export interface Email { id: string sender: string senderEmail?: string /** @deprecated Utiliser `getThreadMessageCount(email)` — ancien compteur participants. */ participantCount?: number subject: string preview: string /** HTML body — rendu dans une iframe sandbox pour raisons de sécurité */ body?: string /** ISO 8601 avec fuseau — affichage via `formatMail*` / `MailDateText` */ date: string read: boolean starred: boolean important: boolean spam?: boolean hasAttachment?: boolean hasInvitation?: boolean /** ICS / métadonnées — utilisé pour la carte invitation + détection visio */ calendarInvitation?: CalendarInvitationMeta attachments?: EmailAttachment[] tag?: string /** Corbeille : pseudo-dossier `trash` quand true */ deleted?: boolean /** Libellés / dossiers associés à cette conversation */ labels?: string[] /** Messages précédents dans la conversation (le dernier message est le body principal) */ conversation?: ConversationMessage[] /** ISO 8601 — heure d’envoi prévue (dossier Planifié) */ scheduledSendAt?: string /** Prénom ou libellé pour la colonne « À : … » */ scheduledToName?: string /** ISO 8601 — fin de mise en attente (dossier En attente) */ snoozeWakeAt?: string /** Id du message le plus récent du fil (tête). Égal à `id` si message seul. */ threadHeadId?: string /** Ids de tous les messages du fil, du plus ancien au plus récent. */ threadMessageIds?: string[] /** En mode conversation, seuls les messages tête apparaissent en liste. */ isThreadHead?: boolean } export { getThreadMessageCount, normalizeLegacyEmailCatalog, } from "@/lib/mail-thread" import { normalizeLegacyEmailCatalog } from "@/lib/mail-thread" const legacyEmails: Email[] = [ ...demoCalendarInvitationEmails, { id: "1", sender: "ronenrozn... Daniel", senderEmail: "notifications@github.com", participantCount: 3, subject: "Re: [ollama/ollama] 0.23.1 : mlx runner failed (Issue #16007)", preview: "- Closed #16007 as completed via #16053. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this bec...", body: `

Closed #16007 as completed via #16053.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.

`, date: "2026-05-16T01:38:00+02:00", read: false, starred: false, important: false, hasAttachment: true, attachments: [ { name: "CELTICOM_bulletin.pdf", kind: "pdf", sizeBytes: 482_910 }, { name: "mlx_trace.png", kind: "image", sizeBytes: 128_440 }, { name: "notes.txt", kind: "other", sizeBytes: 2_048 }, { name: "build_log.pdf", kind: "pdf", sizeBytes: 1_024_512 }, ], labels: ["inbox"], conversation: [ { id: "1-a", sender: "ronenrozn", senderEmail: "ronenrozn@users.noreply.github.com", date: "2026-05-12T23:15:00+02:00", read: false, preview: "After upgrading to 0.23.1, the mlx runner fails to start on Apple Silicon. Error: mlx_runner: failed to load model...", body: `

After upgrading to 0.23.1, the mlx runner fails to start on Apple Silicon.

Error: mlx_runner: failed to load model
  at MLXRunner.init (runner.go:142)
  at Server.loadModel (server.go:89)

Environment:

`, }, { id: "1-b", sender: "Daniel", senderEmail: "daniel@ollama.ai", date: "2026-05-13T00:42:00+02:00", preview: "Thanks for reporting. This is a known regression in the MLX backend. We have a fix in #16053 that should resolve...", body: `

Thanks for reporting. This is a known regression in the MLX backend.

We have a fix in #16053 that should resolve this. Can you try building from the fix/mlx-runner branch?

`, }, ], }, { id: "2", sender: "Reçu Uber", senderEmail: "noreply@uber.com", participantCount: 2, subject: "[Personal] Votre course de jeudi matin en Uber", preview: "- 7 mai 2026 1:11 7 mai 2026 , 1:11 Eliott, merci d'avoir utilisé Uber Nous espérons que vous avez apprécié votre course ce ma...", body: `

Eliott, merci d'avoir utilisé Uber

Nous espérons que vous avez apprécié votre course ce matin.

Date7 mai 2026, 1:11
TrajetParis 11e → Gare de Lyon
Total12,34 €
`, date: "2026-05-07T01:11:00+02:00", read: true, starred: false, important: false, attachments: [{ name: "recu_course.pdf", kind: "pdf", sizeBytes: 88_320 }], labels: ["inbox", "Factures", "Achats", "Promotions"], }, { id: "3", sender: "SannyGro., thehelme.", senderEmail: "notifications@github.com", participantCount: 2, subject: "Re: [IceWhaleTech/ZimaOS] [Info] Installation on Proxmox VE 8.0.4 as a VM (Issue #5)", preview: "- thehelmethedheinsight left a comment (IceWhaleTech/ZimaOS#5) I just wrote the .img t...", body: `

thehelmethedheinsight left a comment (IceWhaleTech/ZimaOS#5)

I just wrote the .img to a usb stick with Balena Etcher, but linux 'dd' will work as well.

In Proxmox > Create VM, don't add media to the CD/DVD-rom device. ADD a USB device, plug in the USB stick that you imaged to (Etcher, dd).

Redirect Proxmox USB dev to that USB stick. Choose a UEFI BIOS, start the VM. During startup, press ESC to go into BIOS > set boot order - USB first. Proxmox should boot off the physical usb stick.

Install to your virtual HDD with the ZimaOS setup. I chose 64GB to play around with.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.

`, date: "2026-04-05T12:00:00+02:00", read: true, starred: false, important: false, labels: ["inbox", "Réseaux sociaux"], conversation: [ { id: "3-a", sender: "SannyGrooves", senderEmail: "sannygrooves@users.noreply.github.com", date: "2026-03-14T11:55:00+01:00", preview: "SannyGrooves left a comment (IceWhaleTech/ZimaOS#5) Just wanted to say: Big shoutout to Rogger for this automated installation script. Just run in Proxmox SSH (", body: `

SannyGrooves left a comment (IceWhaleTech/ZimaOS#5)

Just wanted to say: Big shoutout to Rogger for this automated installation script. Just run in Proxmox SSH and it does everything for you.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.

`, }, ], }, { id: "4", sender: "parse-git., Istarkgv", senderEmail: "notifications@github.com", participantCount: 2, subject: "Re: [parse-community/parse-server] Implement an MCP Server to let AI help with debugging Parse Server Instances, SCHEMAs, data... (Issue #9948)", preview: "- Istarkgv left a comment ...", body: `

Istarkgv left a comment on parse-community/parse-server#9948

This is a great idea. I've been thinking about how we could leverage MCP servers to make Parse Server more accessible to AI agents.


Reply to this email directly, view it on GitHub, or unsubscribe.

`, date: "2026-03-19T10:00:00+01:00", read: true, starred: false, important: false, labels: ["inbox", "Mises à jour"], }, { id: "5", sender: "Pyxage .. Argenis", senderEmail: "notifications@github.com", participantCount: 7, subject: "Re: [zeroclaw-labs/zeroclaw] Feature parity checklist: OpenClaw → ZeroClaw migration blockers (Issue #88)", preview: "- Closed #88 as completed via 80ce59f. You are receiving this bec...", body: `

Closed #88 as completed via 80ce59f.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.

`, date: "2026-02-28T12:00:00+01:00", read: true, starred: true, important: false, labels: ["inbox", "starred", "Travail", "Forums"], conversation: [ { id: "5-a", sender: "Pyxage", senderEmail: "pyxage@users.noreply.github.com", date: "2026-02-10T14:22:00+01:00", preview: "This issue tracks the remaining feature parity gaps between OpenClaw and ZeroClaw. Blockers: 1. Plugin system...", body: `

This issue tracks the remaining feature parity gaps between OpenClaw and ZeroClaw.

Blockers:

  1. Plugin system — needs adapter layer
  2. Config migration tool — partial
  3. Webhook retry logic — missing
  4. Rate limiting — different algorithm
`, }, { id: "5-b", sender: "Argenis", senderEmail: "argenis@zeroclaw-labs.com", date: "2026-02-19T09:10:00+01:00", preview: "Update: items 1-3 are resolved. Rate limiting will ship in v2.4. Moving to close once CI passes...", body: `

Update: items 1-3 are resolved. Rate limiting will ship in v2.4.

Moving to close once CI passes on 80ce59f.

`, }, ], }, { id: "6", sender: "Reçu Uber", senderEmail: "noreply@uber.com", participantCount: 2, subject: "[Personal] Votre course de samedi matin en Uber", preview: "- 28 févr. 2026 2:10 28 févr. 2026 , 2:10 Voici le récapitulatif des frais Ce document confirme que votre trajet est terminé. T...", body: `

Voici le récapitulatif des frais

Ce document confirme que votre trajet est terminé.

Date28 févr. 2026, 2:10
TrajetMontmartre → Bastille
Total18,50 €
`, date: "2026-02-28T02:10:00+01:00", read: false, starred: false, important: true, hasInvitation: true, labels: ["inbox", "Factures"], }, { id: "7", sender: "vercell[., iaraong.", senderEmail: "notifications@github.com", participantCount: 3, subject: "Re: [wiarabeauty/frontend] Tabbar (PR #138)", preview: "- Merged #138 into dev. — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you w...", body: `

Merged #138 into dev.


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.

`, date: "2026-02-27T12:00:00+01:00", read: true, starred: false, important: false, labels: ["sent", "[Imap]/Sent"], }, { id: "8", sender: "iaraongit, vercell[b.", senderEmail: "notifications@github.com", participantCount: 3, subject: "[wiarabeauty/frontend] Dev (PR #135)", preview: "- You can view, comment on, or merge this pull request online at: https://github.com/wiarabeauty/frontend/pull/135 Commit Summary ...", body: `

You can view, comment on, or merge this pull request online at:

https://github.com/wiarabeauty/frontend/pull/135

Commit Summary

`, date: "2026-02-23T12:00:00+01:00", read: true, starred: false, important: false, labels: ["drafts"], }, { id: "9", sender: "vercell[., iaraong.", senderEmail: "notifications@github.com", participantCount: 3, subject: "Re: [wiarabeauty/frontend] Dev (PR #130)", preview: "- Closed #130. You are receiving this because you were mentioned.Message ID:

Closed #130.


You are receiving this because you were mentioned.
Message ID: <wiarabeauty/frontend/pull/130/issue_event/22471S3>

`, date: "2026-02-23T15:30:00+01:00", read: true, starred: false, important: false, labels: ["inbox", "CCTV"], }, { id: "10", sender: "Reçu Uber", senderEmail: "noreply@uber.com", participantCount: 2, subject: "[Personal] Votre course de vendredi matin en Uber", preview: "- 30 janv. 20263:5530 janv. 2026 , 3:55Voici le récapitulatif des frais Ce document confirme que votre trajet est terminé...", body: `

Voici le récapitulatif des frais

Ce document confirme que votre trajet est terminé.

Date30 janv. 2026, 3:55
Total22,10 €
`, date: "2026-02-02T03:55:00+01:00", read: true, starred: false, important: false, labels: ["inbox", "Déplacements"], }, { id: "11", sender: "Iman .. Pegasus", senderEmail: "notifications@github.com", participantCount: 4, subject: "Re: [parse-community/parse-dashboard] Time zone support (#482)", preview: "- leonace924 left a comment (parse-community/parse-dashboard#482) @mtrezza What is your worki...", body: `

leonace924 left a comment on parse-community/parse-dashboard#482

@mtrezza What is your working branch for this feature? I'd like to contribute some timezone utilities.

`, date: "2026-01-30T12:00:00+01:00", read: true, starred: false, important: false, labels: ["inbox", "Clients"], }, { id: "12", sender: "Chez Ma Tante", senderEmail: "contact@chezmatante.fr", participantCount: 2, subject: "Invitation à rejoindre Fast Forward sur Chez Ma Tante", preview: "- Bienvenue ! 🎉 Bonjour Jean Dupont, Vous avez été invité à rejoindre Fast Forward sur Chez Ma Tante ! Voici vos identifi...", body: `

Bienvenue ! 🎉

Bonjour Jean Dupont,

Vous avez été invité à rejoindre Fast Forward sur Chez Ma Tante !

Voici vos identifiants de connexion :

Se connecter

`, date: "2026-01-09T12:00:00+01:00", read: true, starred: false, important: false, hasInvitation: true, labels: ["inbox", "BrowserAlerts", "Twitch"], }, { id: "13", sender: "parse-git. .. Taufik", senderEmail: "notifications@github.com", participantCount: 4, subject: "[parse-community/parse-server] Google Auth: No sessionToken sent from linkWith or loginWith (Issue #8853)", preview: "- Thanks for opening this issue! 🎯 You can help us...", body: `

Thanks for opening this issue! 🎯

You can help us by providing the following information:

`, date: "2025-12-29T12:00:00+01:00", read: true, starred: false, important: false, labels: ["inbox", "Q1 2026", "CMSecurity Alerts"], }, { id: "14", sender: "parse-git. .. Manuel", senderEmail: "notifications@github.com", participantCount: 12, subject: "Re: [parse-community/parse-server] docs: Added AI Integration section to use parse-mcp to help AI Agents interact with Parse (PR #9949)", preview: "- mtrezza left a comment (parse-c...", body: `

mtrezza left a comment on parse-community/parse-server#9949

Great addition to the docs! A few suggestions:

  1. Add a note about authentication requirements
  2. Include example MCP configuration
  3. Mention supported Parse Server versions
`, date: "2025-12-01T12:00:00+01:00", read: true, starred: false, important: false, labels: ["inbox", "Travail", "RH"], conversation: [ { id: "14-a", sender: "parse-github-assistant", senderEmail: "parse-github-assistant[bot]@users.noreply.github.com", date: "2025-11-28T10:00:00+01:00", preview: "Thanks for opening this pull request! A maintainer will review it shortly...", body: `

Thanks for opening this pull request! 🎯

A maintainer will review it shortly. Please make sure:

`, }, { id: "14-b", sender: "R3D347HR4Y", senderEmail: "r3d347hr4y@users.noreply.github.com", date: "2025-11-28T14:32:00+01:00", preview: "Here is the initial PR adding the AI Integration docs section. It covers MCP server setup, authentication...", body: `

Here is the initial PR adding the AI Integration docs section. It covers:

Happy to iterate based on feedback!

`, }, { id: "14-c", sender: "dblythy", senderEmail: "dblythy@users.noreply.github.com", date: "2025-11-29T08:15:00+01:00", preview: "Looks good overall! One concern: the auth section should mention that Parse Server keys are required...", body: `

Looks good overall! One concern: the auth section should mention that Parse Server master key is never to be exposed to AI agents in production.

Suggestion: add a security callout box.

`, }, ], }, { id: "15", sender: "parse-githu., Manuel", senderEmail: "notifications@github.com", participantCount: 2, subject: "Re: [parse-community/parse-server] Allow editing createdAt in cloud code (Issue #9889)", preview: "- parse-github-assistant[bot] left a comment (parse-community/parse-serve...", body: `

parse-github-assistant[bot] left a comment on parse-community/parse-server#9889

This issue has been automatically marked as stale because it has not had recent activity.

`, date: "2025-11-05T12:00:00+01:00", read: true, starred: false, important: false, labels: ["inbox"], }, { id: "16", sender: "Reçu Uber", senderEmail: "noreply@uber.com", participantCount: 2, subject: "[Personal] Votre course de samedi matin en Uber", preview: "- 1 nov. 2025 2:55 1 nov. 2025 , 2:55 Eliott, merci d'avoir utilisé Uber Nous espérons que vous avez apprécié votre course ...", body: `

Eliott, merci d'avoir utilisé Uber

Nous espérons que vous avez apprécié votre course ce samedi matin.

`, date: "2025-11-01T02:55:00+01:00", read: true, starred: false, important: false, labels: ["inbox", "Voyages"], }, { id: "17", sender: "GitHub", senderEmail: "noreply@github.com", subject: "[GitHub] Your personal access token (classic) is about to expire", preview: "- Hi @R3D347HR4Y, We noticed your personal access token (classic) \"caprover-test\" with read.enterprise and...", body: `

Hi @R3D347HR4Y,

We noticed your personal access token (classic) "caprover-test" with read.enterprise scope is about to expire.

To avoid any disruptions, please regenerate your token before it expires.

Regenerate token

`, date: "2025-09-30T12:00:00+02:00", read: true, starred: false, important: false, hasInvitation: true, attachments: [ { name: "screenshot.png", kind: "image", sizeBytes: 412_000 }, { name: "notes.txt", kind: "other", sizeBytes: 1_280 }, ], labels: ["inbox", "Finance"], }, { id: "18", sender: "olivier delmas", senderEmail: "olivier.delmas.1@gmail.com", participantCount: 6, subject: "Invitation: Task Force : rdv en incidents - jeu. 14 mai 2026 14:30 - 15:30 (UTC+2) (moi@example.com)", preview: "Invitation à un événement Google Meet : Task Force : rdv en incidents — jeu. 14 mai 2026 14:30 – 15:30 (heure d’Europe centrale)", body: `

Vous êtes invité·e à une réunion Google Meet.

Task Force : rdv en incidents
jeu. 14 mai 2026 14:30 – 15:30 (heure d’Europe centrale)

Rejoindre la réunion

`, date: "2025-09-30T10:13:00+02:00", read: true, starred: false, important: false, hasInvitation: true, labels: ["inbox", "Travail"], hasAttachment: true, calendarInvitation: { ics: `BEGIN:VCALENDAR VERSION:2.0 CALSCALE:GREGORIAN METHOD:REQUEST BEGIN:VEVENT DTSTART;TZID=Europe/Paris:20260514T143000 DTEND;TZID=Europe/Paris:20260514T153000 DTSTAMP:20260513T101300Z ORGANIZER;CN=Olivier Delmas:MAILTO:olivier.delmas.1@gmail.com UID:demo-task-force@ultimail.test ATTENDEE;CN=maz@iarabeauty.com:MAILTO:maz@iarabeauty.com ATTENDEE;CN=agathe@iarabeauty.com:MAILTO:agathe@iarabeauty.com ATTENDEE;CN=melanie.grc@hotmail.fr:MAILTO:melanie.grc@hotmail.fr ATTENDEE;CN=foujeupavel@example.com:MAILTO:foujeupavel@example.com SUMMARY:Task Force : rdv en incidents LOCATION:https://meet.google.com/abc-defg-hij DESCRIPTION:Réunion visio\\nLien Meet: https://meet.google.com/abc-defg-hij END:VEVENT END:VCALENDAR`, }, attachments: [ { name: "invite.ics", kind: "other", sizeBytes: 3_400, inlineText: `BEGIN:VCALENDAR VERSION:2.0 METHOD:REQUEST BEGIN:VEVENT DTSTART;TZID=Europe/Paris:20260514T143000 DTEND;TZID=Europe/Paris:20260514T153000 ORGANIZER;CN=Olivier Delmas:MAILTO:olivier.delmas.1@gmail.com UID:demo-task-force@ultimail.test ATTENDEE;CN=maz@iarabeauty.com:MAILTO:maz@iarabeauty.com ATTENDEE;CN=agathe@iarabeauty.com:MAILTO:agathe@iarabeauty.com ATTENDEE;CN=melanie.grc@hotmail.fr:MAILTO:melanie.grc@hotmail.fr ATTENDEE;CN=foujeupavel@example.com:MAILTO:foujeupavel@example.com SUMMARY:Task Force : rdv en incidents LOCATION:https://meet.google.com/abc-defg-hij END:VEVENT END:VCALENDAR`, }, { name: "notes.txt", kind: "other", sizeBytes: 890 }, ], }, { id: "19", sender: "Service livraison express", senderEmail: "shipping-express-notif@scam-domain.xyz", subject: "Dernier avis : colis bloqué — frais douaniers à payer sous 24 h", preview: "- Votre envoi n°4829103 est retenu. Régularisez ici : bit.ly/... (ne pas répondre à ce message)", body: `

⚠️ ATTENTION : Dernier avis avant retour à l'expéditeur

Votre envoi n°4829103 est retenu en douane. Des frais de 2,99 € doivent être réglés sous 24 h.

PAYER MAINTENANT

Ne pas répondre à ce message.

`, date: "2025-09-26T12:00:00+02:00", read: false, starred: false, important: false, spam: true, labels: ["spam"], }, { id: "20", sender: "Reçu Uber", senderEmail: "noreply@uber.com", participantCount: 2, subject: "[Personal] Votre course de dimanche matin en Uber", preview: "- Total 66,61 € 21 septembre 2025 Merci d'avoir choisi Uber One, Eliott Nous espérons que vous avez apprécié votre c...", body: `

Merci d'avoir choisi Uber One, Eliott

Nous espérons que vous avez apprécié votre course ce dimanche matin.

Date21 septembre 2025
Total66,61 €
`, date: "2025-09-21T12:00:00+02:00", read: true, starred: false, important: false, labels: ["inbox", "Famille"], }, { id: "21", sender: "LottoVIP", senderEmail: "winner-notification@lottovip-scam.net", subject: "Félicitations ! Vous êtes le grand gagnant — réclamez votre prix", preview: "- Cliquez maintenant pour recevoir 1 000 000 €. Offre limitée. Désabonnement impossible.", body: `

🎉 FÉLICITATIONS ! 🎉

Vous avez été sélectionné comme GRAND GAGNANT de notre loterie internationale !

1 000 000 €

Pour réclamer votre prix, cliquez sur le lien ci-dessous :

RÉCLAMER MON PRIX

Offre limitée. Désabonnement impossible.

`, date: "2025-09-20T12:00:00+02:00", read: true, starred: false, important: true, spam: true, labels: ["spam"], }, { id: "22", sender: "Les Amis du Louvre", senderEmail: "newsletter@louvre.fr", subject: "Lettre des Amis du Louvre — mai 2026", preview: "- Expositions, conférences et coulisses du musée : découvrez le programme du mois.", body: `

Bonjour,

Voici la lettre de mai des Amis du Louvre : parcours Napoléon, nocturnes et ateliers jeune public.

Lire la lettre en ligne

`, date: "2026-05-12T08:00:00+02:00", read: false, starred: false, important: false, labels: ["inbox", "Newsletters"], }, { id: "23", sender: "The Washington Post", senderEmail: "newsletters@washpost.com", subject: "The Daily 202 : ce qu’il faut retenir ce matin", preview: "- Analyses politiques et agenda de Washington — édition du 11 mai.", body: `

Good morning — here’s what we’re watching today on Capitol Hill and beyond.

Read today’s edition

`, date: "2026-05-11T07:00:00+02:00", read: true, starred: false, important: false, labels: ["inbox", "Newsletters"], }, ] export const emails: Email[] = normalizeLegacyEmailCatalog(legacyEmails)