Holiday Recap
Catch the user up after annual leave or any extended out-of-office period. Reviews Outlook email, meeting invitations, meetings held while away, Teams channels, group chats, 1:1 chats and meeting chats, then reports Mails, Meeting Request, Important Meetings Recap and Chats — each item appearing exactly once, deep-linked, styled to match the app it came from (Outlook items read like Outlook, Teams items read like Teams) — before executing the meeting responses, sends and posts the user approves.
When NOT to Use
- Daily or end-of-day catch-up ("what did I miss today", "morning briefing") →
daily-briefing. - A single meeting's summary, transcript or action items →
meeting-intel. - Calendar hygiene, declining low-value meetings, defending focus time →
calendar-management. - Booking, moving or cancelling a meeting →
schedule-meeting. - Ordinary inbox triage or a one-off email search → use the Outlook tools directly.
- Absences of roughly a day or less, where a daily briefing is the better fit.
This skill orchestrates those built-in capabilities across a multi-day absence window; it does not replace them. Where a built-in skill does the job better for one item (e.g. a deep meeting summary), use it and fold the result into the recap.
Workflow
Step 1 — Ask the scoping questions, starting with which areas to cover
Before any mailbox, calendar, chat or channel call runs, ask the user through this sequence,
starting with Q0. Combine into as few core-AskUserQuestion cards as the UI allows (e.g. Q0
alone on its own card since every later question depends on it; Q1 alone on the next card since
it gates everything else; Q2+Q3 together where relevant; Q4 alone, since its answer determines
what the next card can even show; Q5 next; Q6 last) — but the fixed order below never changes,
and a question is only skipped when its own rule below says to skip it.
Q0 — Areas to include "Which areas do you want covered in this recap?" Multi-select, presented as checkboxes:
- ✅ Mails
- ✅ Meeting Requests
- ✅ Important Meetings Recap
- ✅ Teams Channels
- ✅ Teams Group Chats
- ✅ Teams 1:1 Chats
- ✅ Meeting Chats
- ✅ Include everything
Rules:
- "Include everything" is a shortcut for selecting all seven areas — offer it alongside the individual checkboxes, not instead of them, so the user can also multi-select only what they want.
- This answer decides which of Q1–Q6 are asked next — see the per-question skip rules below. Never ask a follow-up question that only serves an area the user did not select.
- Q0 itself is never skipped, even when the user's own words already name a period or person — those words answer Q1/Q2, not Q0. If no areas are selected (a blank or cancelled answer), re-ask once in plain language; a recap with zero areas selected produces nothing to report.
- The Output Structure only shows the sections for areas actually selected — omit an unselected section's heading entirely rather than showing it empty. If only some areas were chosen, say so plainly at the top of the recap (e.g. "Covering Mails and Meeting Requests only, per your selection").
Q1 — Time period
outlook_calendar-ListCalendarViewover a generous window (default: the last 60 days through today) and identify events whereshowAsisoof, or the subject clearly marks leave (OOO, PTO, annual leave, vacation, holiday). Also checkoutlook-GetAutoReplySettings— an automatic-reply window is strong corroborating evidence.- Infer the likely continuous absence from those events:
- Merge adjacent OOF blocks separated only by weekends or public holidays.
- Treat half-days as partial cover and flag them rather than silently rounding.
- Ignore cancelled OOF entries and isolated one-off OOF appointments (a single afternoon block is not a holiday); mention them only if they sit adjacent to the main block.
- If several distinct blocks exist, present them as candidate options.
- Ask the user to pick, offering exactly these two paths:
- (a) Auto-detect from last out-of-office — show the detected block(s) (dates and times) for the user to confirm or correct, defaulting the catch-up end time to now.
- (b) Enter custom — a free date-and-time range from the user.
- Custom range path. If the user picks (b), states dates directly in their request
("catch me up between 4 and 18 August", "what did I miss since last Tuesday", "recap the
last two weeks"), or the calendar holds no OOF entries at all (so (a) has nothing to show),
take the range from the user. Rules:
- Resolve relative phrases ("last two weeks", "since Monday") to explicit dates in the user's local time zone and echo them back for confirmation before proceeding.
- Accept times as well as dates; when only dates are given, default the start to 00:00 and the end to the current time (or 23:59 for a past end date).
- Reject an invalid range (end before start, a future start, a window longer than 90 days) and ask again rather than silently correcting it.
- Record the source of the period in the output: "Detected from calendar" or "Provided by user".
- If the calendar evidence is unclear, absent or contradictory and the user has not given a range, say so plainly and ask for the dates. Never assume the period.
Q2 — Priority senders (ask only if Mails, any Teams chat/channel area, or "Include
everything" was selected in Q0 — skip entirely if only Meeting Requests and/or Important
Meetings Recap were chosen, since neither has a "sender" concept beyond the organizer)
"Do you want to prioritize mail or messages from any person? Enter full name(s) or email
address(es), separated by semicolons." Free text, optional — blank means no override. Accepts
names, email addresses, or a mix (e.g. Jordan Blake; sam.rivera@example.com).
Q3 — Priority keywords (ask whenever Q2 is asked — same skip condition) "Do you want to prioritize any keywords (e.g. a subject, a customer name)? Separate multiple values with semicolons." Free text, optional — blank means no override.
Q4 — Teams to include (ask only if Teams Channels, or "Include everything", was selected in
Q0 — skip entirely if Teams Channels was not chosen, even when other Teams areas like Group
Chats or 1:1 Chats were, since only channels are scoped by team)
Call m365_teams-ListTeams and present a ranked shortlist of high-priority teams (posted in / mentioned
in recently, then name-matched to the user's accounts, projects or org) as selectable options,
plus a free-text field to add other team names, semicolon-separated, for anything not on the
shortlist. When asked, this question is mandatory — see the Teams channel scope rule in Step 2.
Also offer "Scan all teams" and "Skip Teams channels" as explicit options alongside the shortlist.
Q5 — Channels to include, per team (ask only when Q4 was asked and answered with at least
one team — skip entirely under the same condition as Q4, and skip per-team as described below)
For each team selected in Q4 (skip entirely if Q4 was "Skip Teams channels"), call
m365_teams-ListChannels and present a ranked shortlist of high-priority channels for that team
(channels the user has posted or been mentioned in, then name-matched to their accounts and
projects), grouped under the team's name, plus a free-text field per team to add other
channel names, semicolon-separated. Skip this question for a team if the user chose "Scan all
teams" in Q4, or if that team has ten channels or fewer — scan it whole and say so. Never scan
a channel that was not selected or explicitly named.
Q6 — Any other instructions (always asked, regardless of Q0) "Add any other instruction before I start the report generation." Free text, optional. Capture verbatim and apply it throughout generation (Step 3 onward) as long as it does not conflict with the Guardrails below — e.g. it can reorder or emphasise sections, narrow the audience, change tone, or add a filter, but it can never authorise skipping approval before a send, post or calendar action.
Rules for the whole scoping step
- Wait for all applicable answers before any search runs. No mailbox, calendar, chat or channel call fires until Q0 and every question Q0 makes relevant have been answered (Q2/Q3/Q4/Q5 may legitimately be skipped entirely per their own conditions above).
- A question skipped because Q0 ruled it out is not "unanswered" — treat it as answered with "not applicable — area not selected" for the purposes of "wait for all answers," and never silently ask it later in the same task.
- Skip a question only when the user's own words already answer it, or Q0's condition rules it out — "catch me up on email from Jordan last week" answers Q1 and Q2; echo back what you inferred and still ask the rest that remain relevant per Q0.
- A cancelled or blank answer to Q2, Q3 or Q6 is a valid answer — it means no override, not "ask again." A cancelled or blank answer to Q1 or Q4 is not permission to guess — re-ask Q1 once in plain language; for Q4, if the user cancels again, skip Teams channels entirely and say so.
- Record every confirmed answer and reuse it for the rest of the conversation — never re-ask Q0–Q6 on a follow-up in the same task.
- Echo the full scope back at the top of the recap — areas covered, period, priority senders, priority keywords, teams and channels scanned, and any other instruction received — so the user can see exactly what shaped the report, including which areas were left out and why.
Step 2 — Search the confirmed period
Only search content the user already has permission to access. Run independent searches in
parallel and track progress with core-TaskCreate / core-TaskUpdate.
| Source | Tools |
|---|---|
outlook-ListMessages, m365_search-SearchM365 (sources: message), outlook-GetMessage |
|
| Calendar & invitations | outlook_calendar-ListCalendarView (absence window and forward window) |
| Meetings held while away | outlook_calendar-ListCalendarView → graph-ListMeetingTranscripts → graph-GetMeetingTranscript (per-meeting joinUrl path) |
| Meeting chat / shared content | m365_teams-ListChatMessages, sharepoint_onedrive-SearchDrive |
| Teams channels | m365_teams-ListTeams, m365_teams-ListChannels, m365_teams-ListChannelMessages |
| Teams group chats | m365_teams-ListChats (chatType: group), m365_teams-ListChatMessages |
| One-to-one chats | m365_teams-ListChats (chatType: oneOnOne), m365_teams-ListChatMessages |
| Meeting chats | m365_teams-ListChats (chatType: meeting), m365_teams-ListChatMessages |
| @mentions in mail | m365_search-SearchM365 (sources: message, query scoped to the user's own name/mention markup) or scan message bodies for a mention tag matching the user |
| @mentions in chat/channel | each message's mentions[] array from m365_teams-ListChatMessages / m365_teams-ListChannelMessages, matched against the user's identity |
| Work-pattern signal (Step 4) | outlook-ListMessages (Sent Items), me_profile-GetManagerDetails, me_profile-GetDirectReportsDetails, outlook_calendar-ListEvents (prior 60 days, responseStatus) |
Only search the sources for areas selected in Q0. Skip an entire row of the table above (and
the tool calls it implies) when its area was not selected — e.g. if Teams Group Chats was not
chosen, never call m365_teams-ListChats with chatType: group at all, rather than calling it and
discarding the results. Calendar & invitations is searched whenever Meeting Requests, Important
Meetings Recap, or Meeting Chats was selected (each draws on the calendar window); email is
searched whenever Mails was selected.
Teams channel scope comes from Q4 and Q5 in Step 1 — do not re-derive it here. Use exactly the teams and channels the user selected (plus any semicolon-separated names they typed in) as already confirmed; never widen or narrow that set during the search itself. This entire step is itself skipped if Teams Channels was not selected in Q0.
Priority senders and keywords (Q2, Q3) apply across every source, not just email. Treat a
match — the sender/author is on the Q2 list, or the subject/body/message contains a Q3 term —
as a standing signal that elevates the item at least one bucket (e.g. an item that would
otherwise be "For Awareness" becomes "Action Required" if strongly on-topic, or is at minimum
promoted to the top of its bucket) and earns a short ⭐ priority match marker on the item. A
priority match never demotes an item that already qualifies for a higher bucket on its own
merits, and never fabricates urgency the content does not support — it re-ranks and flags, it
does not invent a request that was not made.
Any other instruction (Q6) is applied throughout Steps 2–7 wherever it does not conflict with the Guardrails — e.g. "skip customer story emails" narrows Step 4's inclusion, "focus on the Fabrikam account" reorders the action plan, "keep it short" tightens the presentation rules. State in the recap header that a custom instruction was applied and, briefly, what it changed.
Chats — three types, three sections, skip muted. Split Teams chats by chatType and report
each in its own section, never merged:
chatType |
Section |
|---|---|
group |
Teams group chats |
oneOnOne |
One-to-one chats |
meeting |
Meeting chats — the in-meeting and post-meeting chat thread attached to a calendar event |
For a meeting chat, resolve the parent event (match the chat's thread id against the event's
onlineMeeting.joinUrl, or fall back to the chat topic) so the item can be labelled with the
meeting title, organiser and date. Meeting chats often carry the questions that never made it
into the transcript — links dropped in chat, follow-ups posted after the call, and asks aimed
at people who were absent, which includes the user. In all three, exclude any chat the user
has muted — a mute is
an explicit signal that the user does not want to be notified, so treat muted chats as tier 4
and count them rather than listing them. Read the mute state from the chat's
viewpoint.isMuted (or equivalent isMuted field) returned by m365_teams-ListChats; if the field is
absent, treat the chat as unmuted and include it rather than silently dropping it.
Paginate (next_link) until the confirmed window is fully covered. A single page is a sample,
not an answer.
Step 2b — Prepare a suggested reply for every Action Required email (text only, no draft yet)
For every email that will land in Action Required, compose a suggested reply and show it as text in the recap — do not create a real draft object at this stage. No mailbox write happens in Step 2b; nothing is created, saved, or touched in Outlook until the user explicitly asks for it in Step 7.
- The email's own linked title always opens the original message (its
webLink) — never a draft, since none exists yet. - The suggested reply appears directly under the item as quoted text the user can read and judge before anything is created.
- The draft is created only when the user selects that item's action in Step 7 (by number or
by naming it) — at that point, and only then, call
outlook-CreateReplyDraft(oroutlook-CreateReplyAllDraftwhen the reply is owed to the group already on the thread) with the suggested content, then hand the user the real draft's web link to open, edit, and send themselves. Creating the draft is still not the same as sending it —outlook-SendDraftMessageremains a separate, explicit approval. - Never post a Teams equivalent automatically either — a suggested Teams response is shown as text in the recap and only posted on explicit approval, exactly like mail.
- A link never triggers an action by itself. Clicking a link only opens what it points to (the original message); it cannot create, save, or send anything. Any action that changes a mailbox, calendar, or chat happens only because the user named that specific item in Step 7 — never because they clicked a link.
Step 3 — Deduplicate and synthesise
- Cluster items by topic across all seven sources: email, meeting requests, channel messages, group chats, one-to-one chats, meeting chats and meeting recaps.
- A meeting chat and its recap are one topic, not two. Expand the substance under the meeting recap and cross-link from the meeting chat with a one-line pointer — unless the chat carries something the meeting did not (an unanswered question, a link, a post-call follow-up), in which case expand that specific item under Meeting chats and point back to the recap.
- Produce one primary recap item per topic; list every supporting source as a link beneath it.
- Use the latest available status. Do not present something as open if later content shows it was resolved, superseded, answered, or reassigned.
- Never invent decisions, actions, owners, deadlines, dates, meeting content or status. If a detail is not in retrieved content, say it is unclear.
Step 4 — Prioritise on evidence, not flags
Classify from context, not only the Outlook importance flag. Treat an item as high priority when it contains one or more of:
- a direct request or unanswered question addressed to the user;
- an explicit or approaching deadline;
- an action assigned to the user;
- a customer or stakeholder escalation;
- a blocker, risk, approval request, or important decision;
- a message from the user's manager or a key stakeholder needing attention;
- a repeated follow-up;
- a commitment affecting an upcoming meeting or deliverable;
- an unresolved conversation where the user's input is required;
- a match against the user's Q2 priority senders or Q3 priority keywords (see Step 2);
- a match against the user's inferred work pattern (below).
Every high-priority item carries a short Why this matters line.
Statuses: Action needed · Important for awareness · Resolved · Superseded ·
Waiting on another person · Deadline passed · FYI only · Duplicate of another item.
Infer the user's work pattern — a background signal, not a question
Q2/Q3 capture what the user explicitly names; this signal captures what their own behaviour already shows, without asking a seventh question. Derive it once per run, before triage, and reuse it across all seven sources.
- Frequent and fast correspondents. Scan the user's Sent Items for the confirmed
period plus the 60 days before it (
outlook-ListMessageswith the Sent folder, orm365_search-SearchM365). People the user replies to often, and quickly, are a standing priority signal — weight higher than a one-off exchange. - Reporting line and regular 1:1s.
me_profile-GetManagerDetailsandme_profile-GetDirectReportsDetailsidentify the user's manager and reports; recurring 1:1s and skip-levels found in the pre-absence calendar (outlook_calendar-ListEvents, filtered to recurring meetings with 1–2 attendees) add named counterparts to this list. A message from any of them is weighted higher by default, on top of anything named in Q2. - Meetings the user actually keeps vs. lets lapse. Compare accepted/attended meetings
against declined or habitually-ignored recurring invites over the prior 60 days
(
outlook_calendar-ListEventsresponseStatus). Projects, teams, or recurring series the user consistently shows up for indicate real priority; series they routinely decline or leave unanswered do not — even if the series continues during the absence. - Named accounts, projects and teams. Customer, account or project names that recur across the user's own recent sent mail, channel posts and calendar subjects (not merely mentioned to the user) indicate their active portfolio — the same channels and accounts surfaced in Q4/Q5 selections are a strong prior here too.
How this signal is used
- It re-ranks and flags, exactly like a Q2/Q3 match — it can lift an item into a higher
bucket or to the top of one, and earns a short
📈 matches your usual patternmarker. It never fabricates urgency a message does not contain, and it never overrides an explicit Q2/Q3 entry or a Q6 instruction — those are the user's direct word and always win over an inference. - This is inferred, not confirmed — say so plainly wherever it changes an item's placement, so the user can tell inferred priority apart from something they explicitly asked for or that the content itself demands.
- If Sent Items, manager/reports, or historical calendar data cannot be read (permissions, empty mailbox, brand-new hire), skip this signal silently and prioritise on content alone — do not block the recap on it.
Triage every item into exactly one bucket — never duplicated
Every retrieved item is placed into exactly one bucket, in exactly one section. An item never appears twice anywhere in the recap. If an item is relevant to more than one place, it is expanded once — in whichever bucket below comes first for it — and nowhere else.
Mail buckets (in this priority order — an email lands in the first one it qualifies for):
| Bucket | What belongs here |
|---|---|
| Action Required | Meets one or more of the high-priority signals above — the user must do or decide something |
| For Awareness | Materially affects the user's work, team, projects, customers or stakeholders, but needs no action |
| @Mentions | The user is directly @-mentioned in the body, and the email does not already qualify for Action Required or For Awareness |
Meeting Request is its own bucket, independent of the above: every future invitation still awaiting a response, regardless of priority — priority only affects the recommended response.
Chat buckets (Important Teams Channel chat / Important Group Chats / Important 1:1 chats), in this priority order:
| Bucket | What belongs here |
|---|---|
| Important [X] chat | The thread carries something genuinely relevant — a decision, a live discussion, a customer or project update — summarised for the whole period, not message-by-message |
| @Mention in chat | The user is directly @-mentioned somewhere in the thread, and the thread does not already qualify as Important |
A thread that is both Important AND mentions the user stays in "Important" — add a short
🔔 mentions you marker inside that entry rather than creating a second entry under @Mentions.
What never appears in the recap at all (not listed, not counted individually — simply excluded from every bucket): newsletters and subscriptions; marketing and event promotions; automated system/build/pipeline/ticketing/monitoring notifications; delivery and read receipts; out-of-office auto-replies; calendar accept/decline notifications; "thanks"/"+1"/emoji-only replies; social and recognition posts; org-wide announcements with no bearing on the user's work; recruitment mail; join/leave and call-start/end system events in chats.
Exception — include it anyway when the item materially affects the user's work: an automated alert on a system the user owns, a deadline or policy change that applies to them, or a notification someone has explicitly followed up on.
When in doubt whether something clears the bar for a bucket, include it — a missed item the user needed is worse than one extra line. But never invent importance an item does not have just to fill a section.
One quiet line of transparency per top-level section (not a header, just the last line of the section): the count of everything else reviewed and left out, e.g. "204 other emails reviewed — no action or awareness needed." This is the only place volume is disclosed; it is never expanded into a list.
Step 5 — Produce the recap in the structure below
Step 6 — Links and traceability
Default: every item in the recap is a link, and that link opens the item itself. This applies to every bucket, in every section — an item is only ever left as plain text through the single explicit fallback below, after every recovery route has genuinely been exhausted. "The tool didn't return a link" is not a reason to skip the link; it is the trigger for the recovery ladder in the Rules below.
The link must deep-link to the item, not to its container. A link to an inbox, a channel home, a chat list or a calendar view is NOT acceptable — the user must land on the exact message, invitation, post or meeting.
| Item | Deep link to use |
|---|---|
the message's webLink from outlook-ListMessages / outlook-GetMessage — opens that message in Outlook |
|
| Draft reply | the draft's own webLink from outlook-CreateReplyDraft — opens the draft, ready to review and send |
| Meeting request / calendar event | the event's webLink from outlook_calendar-ListCalendarView / outlook_calendar-ListEvents |
| Meeting join | the event's onlineMeeting.joinUrl |
| Teams channel post | the message's webUrl from m365_teams-ListChannelMessages — includes the message id, so it opens the post in place. m365_teams-ListChannelMessages frequently omits webUrl; when it does, do NOT fall back to plain text — recover the link (see the Teams link-recovery rule below) so every channel item still carries one |
| Group / 1:1 / meeting chat message | the message's webUrl from m365_teams-ListChatMessages. Chat messages very often return webUrl: null; when they do, recover the link (see the Teams link-recovery rule below) rather than dropping to plain text, and still name the author and timestamp alongside it |
| File, deck or recap | the attachment's or drive item's contentUrl / webUrl |
Rules
- Make the item's own title the link. Write
**[Subject](url)**, not a title followed by a bare "[link]" — the user should click the thing they are reading. - Take the URL verbatim from tool output. Never construct, guess, shorten or "correct" one.
- Teams link recovery — every Teams item gets a working link.
m365_teams-ListChannelMessagesandm365_teams-ListChatMessagesroutinely return nowebUrl, and a Teams section rendered without links is a defect, not an acceptable outcome. Before writing a Teams item as plain text, work down this ladder and stop at the first step that yields a link:- Re-request the field. Call
graph-QueryGraphfor that exact message with$select=id,webUrl,from,body,createdDateTime,mentions—/teams/{team-id}/channels/{channel-id}/messages/{message-id}for a channel post,/chats/{chat-id}/messages/{message-id}for a chat message. Use the returnedwebUrlverbatim. - Use the parent's link. For a meeting chat, link the parent event's
webLink(or itsonlineMeeting.joinUrl) fromoutlook_calendar-ListCalendarViewand label it as the meeting the chat belongs to. - Build the standard Teams deep link — the ONE permitted exception to "never construct a URL",
and only for Teams messages. Assemble it from ids the tools returned, never from guesses:
- Channel post:
https://teams.microsoft.com/l/message/{channel-id}/{message-id}?groupId={team-id}&tenantId={tenant-id} - Chat message:
https://teams.microsoft.com/l/message/{chat-id}/{message-id}?context=%7B%22contextType%22%3A%22chat%22%7DPercent-encode nothing beyond what is shown, and use the ids exactly as the tools returned them. Only if all three steps fail doesSource link unavailableapply to a Teams item.
- Channel post:
- Re-request the field. Call
- Preserve the URL byte-for-byte. Do not re-encode, decode, or re-escape any character in the URL (percent-encoding, ampersands, query-string casing) — copy it exactly as the tool returned it. A URL that has been "cleaned up" or reformatted is a broken link, even if it looks tidier.
- If a link opens the wrong item, the general mailbox/inbox, or fails to display, say so plainly rather than presenting it as working — name the item and note the link did not resolve, so the user knows to locate it manually instead of assuming the click will land correctly.
- The single fallback —
Source link unavailable. This is the ONE case in which an item's title is not a link, and it applies only after the routes above have actually been tried and failed: the tool returned no link, a re-request returned none, no parent item carries one, and (for a Teams message) the deep link could not be assembled from ids the tools returned. When it applies, saySource link unavailableand give enough identifying detail (sender/author, exact timestamp, subject or chat name) for the user to find it themselves. Never substitute a container link and never fabricate one — an honestSource link unavailableis correct here, and is not a violation of the every-item-is-a-link default above.
Step 6b — Render Outlook items like Outlook, Teams items like Teams, and make it easy to read
The recap covers two different products, and it should read that way — the eye should know which app an item lives in before reading a word of detail. Chat markdown cannot set an arbitrary font or heading colour, so colour is expressed entirely through the emoji + heading convention below, applied with total consistency — that consistency is what does the job a literal colour would otherwise do. Never fall back to plain, unmarked text for a tier or a source; always carry its icon.
The colour/tier system (use every time, no exceptions)
| Tier or source | Icon | Meaning |
|---|---|---|
| Action Required | 🔴 | Needs the user to do or decide something |
| For Awareness | 🟡 | Worth knowing, nothing to do |
| @Mentions / @Mention in chat | 🔔 | Only reason for inclusion is a direct mention |
| Meeting Request | 📅 | A future invitation awaiting a response |
| Important Meetings Recap | 🎥 | A meeting held during the absence |
| Teams channel / group / 1:1 chat | 💬 | A Teams conversation |
| Important chat subsection heading | 🟣 | The "Important … chat" heading inside the Chats section |
| Suggested reply, not yet created | 📝 | Text ready — picking it in Step 7 creates the real draft |
| Section heading (Mails, Chats) | 📧 / 💬 | Top-level source divider |
Outlook items (Mail, Meeting Request) vs. Teams items (Channel, Group, 1:1, Meeting chats) read differently on purpose:
| Outlook items | Teams items | |
|---|---|---|
| Opening line | The subject, bolded and linked, on its own line | The team▸channel, chat name, or person's name, bolded and linked, on its own line — the title itself carries the link, exactly as for Outlook items; never a plain title followed by a separate "Open thread" link |
| Metadata | A short bullet list under the title — From, Received/When — never crammed onto one line with the title | No "From" bullet — a thread has many authors, so the summary itself carries who said what |
| Body | A one-line quoted summary, then a separate Why important line | A short paragraph summarising the period, written the way a Teams recap reads |
| Meetings specifically | Date and time lead, calendar-invite style | — |
Spacing is not optional — this is the fix for a cramped, hard-to-read recap:
- One blank line between every field inside an item (title, then metadata bullets, then summary, then why-it-matters, then suggested reply). Never join two fields with a middle-dot on the same line — that is exactly the clumsy layout to avoid.
- Metadata is a bullet list, not an inline string. Write:
not- **From:** Sender Name - **Received:** 18 Aug, 14:02**From:** Sender Name · **Received:** 18 Aug, 14:02. - A horizontal rule (
---) between every item within a subsection, so one entry never runs into the next. A horizontal rule also separates every major section (Mails / Important Meetings Recap / Chats / Meeting Request / action plan). - A blank line after every heading before its content starts, and a blank line before the next heading.
- Never wrap multiple items into one paragraph. One item, one clearly bounded block, every time — even when an item is short enough that it "could" fit on fewer lines.
Outlook-style item — spaced out:
📧 **[Subject line](deep-link)**
- **From:** Sender Name
- **Received:** 18 Aug, 14:02
> Quick summary in one or two lines.
**Why important:** the reason, in a phrase.
📝 **Suggested reply:** *(shown as text — no draft exists yet; the deep-link above always opens
the original message. Say "create the draft for <subject>" or pick its number in Step 7 to
actually create it in Outlook.)*
> "The suggested reply text itself, quoted, ready for the user to judge before anything is
> created."
---
Teams-style item — spaced out:
💬 **[Team ▸ #channel](deep-link)**
Summary of the thread for this period, written as a short paragraph — decisions,
asks, and anything still open. No "From" bullet; the paragraph carries the authors.
---
Keep both styles in plain Markdown (no raw HTML, no image embeds, no colour codes) — readability comes from the icon convention, the bulleted metadata, the blank lines, and the horizontal rules above, applied identically every single time.
Output Structure
The recap is emitted as Markdown in the shape below. Sub-blocks shown in fences are literal templates to follow.
Holiday Recap
- Areas covered: <Q0 selection, e.g. "Mails, Meeting Requests, Teams Channels" — or "Everything">
- Start Date/Time:
- End Date/Time:
- Period source: Detected from calendar | Provided by user
- Recap prepared:
- Priority senders: <Q2 list, "none given", or "not applicable — area not selected">
- Priority keywords: <Q3 list, "none given", or "not applicable — area not selected">
- Teams scanned: <team → channels from Q4/Q5>, "none selected", or "not applicable — Teams Channels not selected">
- Other instructions applied: <Q6 text, or "none given">
Prioritised using your usual work pattern — frequent correspondents, your manager/reports, and meetings/accounts you consistently engage with, in addition to the above.
(Emit only the section headings below for areas selected in Q0 — skip an unselected area's heading entirely, do not print it empty. If "Include everything" was chosen, emit all of them.)
📧 Mails (only if Mails was selected)
🔴 Action Required
(one blank line, then the first item — see the Outlook-style item shape above; a horizontal rule after every item, including the last one in the subsection)
If no reply is appropriate for a given item (e.g. the ask is a deadline to hit, not a person to answer), omit that item's suggested-reply line rather than forcing one.
🟡 For Awareness
(same item shape, without the suggested-reply line)
🔔 @Mentions
(same shape; the summary and why-it-matters lines may be dropped if the mention is self-explanatory — but From/Received and the horizontal rule stay)
Closing line, on its own after the last rule: " other emails reviewed — no action or awareness needed."
🎥 Important Meetings Recap *(only if Important Meetings Recap and/or Meeting Chats was
selected)*
Meetings held during the absence worth recapping — a decision was made, an action was assigned, or the discussion materially affects the user's work. Per item, in the Outlook-style shape (date/time leads, calendar-invite style), with the summary written as Decisions / Actions / Unresolved, each its own bullet when there is more than one of a kind:
- **Decisions:** …
- **Actions assigned to you:** … (or "None")
- **Unresolved:** …
If no transcript or recap exists, say so plainly and summarise only from the meeting chat, invitation details and related communications — never imply attendance the user did not have. If only Meeting Chats was selected (not Important Meetings Recap itself), still surface a meeting's chat content here rather than dropping it, but keep the summary limited to what the chat itself carries rather than a full transcript-based recap.
Closing line: " other meetings held — no material recap needed."
💬 Chats (emit only the subsections below whose area was selected in Q0)
🟣 Important Teams Channel chat (only if Teams Channels was selected)
(Teams-style item shape — see above; one rule after each thread)
🟣 Important Group Chats (only if Teams Group Chats was selected)
(same shape)
🟣 Important 1:1 chats (only if Teams 1:1 Chats was selected)
Treat as higher-signal than group chats — a direct message is more likely to be a personal ask still waiting on the user. Same shape.
🔔 @Mention in chat *(only if any of Teams Channels, Teams Group Chats, or Teams 1:1 Chats was
selected — a mention can come from any of them)*
Threads whose only reason for inclusion is a direct mention, not already listed above. Same shape, but the "summary" is simply the message that mentions the user, in context.
Closing line, one per subsection: " other channels/chats reviewed — nothing relevant."
📅 Meeting Request (only if Meeting Requests was selected)
Future invitations awaiting a response. Per item, in the Outlook-style shape, plus:
**Options:**
- [Accept]
- [Tentative]
- [Decline]
- [Propose new time]
- [Follow]
→ action #<n>
- Mark the recommended option in the summary text, but present all five as equally selectable — never a single take-it-or-leave-it choice.
- Propose new time always carries a concrete alternative slot found via
outlook_calendar-FindMeetingTimes— never a bare "propose something else". - Follow takes no calendar action at all — it only means "note this, don't respond." State that plainly next to the option.
- Carry out only the option the user actually picks (Step 7), referenced by its action number.
✅ Recommended action plan
Sequenced by linked title only, one per line with a blank line between — no item bodies repeated. Group under clear sub-headings:
### Today
- [linked title]
### This week
- [linked title]
### Meetings needing a response
- [linked title]
### Meetings needing preparation
- [linked title]
### Suggested replies ready to turn into drafts
- [linked title]
### No further action needed
- [linked title]
Group by customer or project instead, under the same sub-heading pattern, where that reads better for the user.
⚡ Actions I can take for you
The numbered action list from Step 7 — one action per line, grouped under Meetings, Mail drafts, and Teams, each group blank-line-separated, exactly as Step 7 specifies.
Rules
- Every section is a list of items — nothing else. No preamble, no narrative bridge, no recap of another section, no closing commentary beyond the one quiet transparency line.
- An item appears exactly once, in the first bucket it qualifies for. Relevant elsewhere?
That other place gets a one-line pointer —
See 🎥 Fabrikam architecture recap— never a second copy. - Bold the thing that matters and lead with it — the ask, the deadline, the decision. Never open an item with background.
- Quote the source for any claim about what someone asked, decided or committed to — short, in quotation marks, attributed. Do not paraphrase an ask into something vaguer.
- Plain business English — no jargon, no tool names, no internal identifiers or file paths.
- Every item IS a link — the linked title opens the item itself, per Step 6/6b's styling.
- Never cram fields onto one line with a middle-dot separator. Metadata is always a bullet list; a horizontal rule
…(truncated)