Skip to content

feat: Word orchestrator, Outlook skills, WorkIQ integration#45

Merged
sbroenne merged 57 commits intomainfrom
feat/word-orchestrator-outlook-workiq
Feb 26, 2026
Merged

feat: Word orchestrator, Outlook skills, WorkIQ integration#45
sbroenne merged 57 commits intomainfrom
feat/word-orchestrator-outlook-workiq

Conversation

@sbroenne
Copy link
Owner

@sbroenne sbroenne commented Feb 26, 2026

Takes ownership of and rebases PR #33 from @trsdn (Torsten) and @urosstojkic onto current main.

Originally submitted as sbroenne/office-coding-agent#33.

Word tools expanded to 35 (was 10), Outlook tools (22 new), WorkIQ integration,
Word/PPT orchestrators, new skills.
458/458 integration tests passing.

Co-authored-by: Torsten trsdn@users.noreply.github.com
Co-authored-by: urosstojkic urosstojkic@users.noreply.github.com

trsdn and others added 30 commits February 22, 2026 00:15
- Add 'outlook' to OfficeHostApp and AgentHost type unions
- Add Outlook detection in detectOfficeHost()
- Create Outlook agent with read/compose mode guidance
- Create Outlook app prompt
- Create 9 Outlook tools (get_mail_item, get_mail_body, get_mail_attachments,
  set_mail_body, set_mail_subject, add_mail_recipient, reply_to_mail,
  forward_mail, get_user_profile)
- Wire tool routing, system prompt, and agent service for outlook host
- Create separate Outlook manifest (MailApp type)
- Add outlook tool limit test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mEdit form)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
OfficeRuntime.storage requires SharedRuntime which Outlook doesn't support.
Without this fallback, Zustand hydration hangs and the UI is stuck on
'Initializing...'. Now gracefully falls back to localStorage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add optional 'hosts' field to SkillMetadata
- Parse 'hosts' in skill frontmatter
- Filter getSkills() and buildSkillContext() by host
- Filter SkillPicker bundled/imported lists by detected host
- Add hosts: [excel] to Excel skill frontmatter

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Word

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New tools: get_attachment_content, add_file_attachment, remove_attachment,
get_mail_categories, set_mail_categories, remove_mail_categories,
add_notification, remove_notification, save_draft, get_mail_headers,
display_new_message, display_new_appointment, get_diagnostics

Also updated Outlook skill with full tool guidance table.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Queries Exchange calendar via makeEwsRequestAsync with SOAP FindItem.
Returns subject, time, location, organizer for appointments in a date range.
Defaults to today if no dates specified.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Legacy Exchange tokens are disabled in most M365 tenants since 2025.
Added clear error message explaining the limitation and suggesting
Microsoft Graph API with nested app authentication as alternative.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Created src/skills/powerpoint/SKILL.md with tool guidance and workflows
- Registered PowerPoint skill in skillService (host-filtered)
- Expanded POWERPOINT_APP_PROMPT.md with detailed tool selection guide,
  PptxGenJS reference, and constraints documentation
- Removed get_appointments EWS tool from Outlook (legacy tokens deprecated)
- Updated Outlook skill to remove calendar tool reference

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add nested VersionOverridesV1_1 with SupportsPinning=true for both
MessageRead and MessageCompose extension points. This keeps the
task pane open when switching between emails in Outlook.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Recursively traverse group shapes to extract nested text content
- Detect SmartArt/graphics and hint to use get_slide_image as fallback
- Update agent instructions to always try image capture when text is empty

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reverted to simpler text extraction approach without loading shape type
(which fails for certain shape types like SmartArt). Group shape text
extraction now uses try-catch per shape instead of type checking.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The batch context.sync() fails when any shape has an unsupported
textFrame. Now each slide is processed in its own try-catch block
so one problematic slide doesn't break the entire presentation read.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Process each shape with individual context.sync() + try-catch so
  one unsupported textFrame doesn't poison the batch
- Pass options object {width} to getImageAsBase64 instead of raw number

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Base64 PNG at 800px was 72KB+ which exceeds Copilot CLI tool output
limit. Reduced default to 320px, capped max at 400px, and added size
warning when output exceeds 50KB.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Agent now explicitly follows a create→verify→evaluate→refine loop
for every slide modification. Expects 2-3 iterations per slide
instead of one-shot output. Updated both AGENT.md and SKILL.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New tools: get_slide_shapes, get_slide_layouts, get_selected_slides,
get_selected_shapes, add_geometric_shape, add_line, delete_slide,
move_slide, set_slide_background, apply_slide_layout, set_shape_text,
update_shape_style, move_resize_shape, delete_shape.

Now supports: shape styling (fill/outline/font), shape positioning,
slide management (delete/reorder/background/layouts), geometric shapes,
lines, selection queries, and granular shape editing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Updated agent instructions and skill to ALWAYS call get_selected_slides
as the very first step so the agent knows which slide the user is on.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
slide.index is 1-based (what the user sees in PowerPoint) but all
tools expect 0-based slideIndex. Now returns both so the agent uses
the correct index and communicates the correct number to the user.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New tools (10→20 total): insert_paragraph, insert_break,
apply_paragraph_style, set_paragraph_format, get_document_properties,
insert_image, get_comments, insert_list, get_content_controls,
insert_text_at_bookmark.

Created Word skill (SKILL.md) with tool guidance and workflows.
Updated agent with iterative refinement loop and selection awareness.
Expanded app prompt with tool selection guide and HTML formatting tips.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New tools: get_headers_footers, set_header_footer, get_table_data,
add_table_rows, add_table_columns, delete_table_row, set_table_cell_value,
insert_hyperlink, insert_footnote, insert_endnote, get_footnotes_endnotes,
delete_content, insert_content_control, format_found_text, get_sections.

Updated Word skill with new tool guidance and workflows.
Added word/powerpoint host tool limit tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…, and formatting rules

Adapted from reference presentation editing skill patterns:
- Layout variety mandate (never >2 consecutive same layouts)
- Iterative verification loop (create → verify → fix → re-verify)
- Template adaptation pitfalls (content count/length mismatch)
- PptxGenJS formatting rules (bold, bullets, colors, margins, fonts)
- Verification checklist (overlap, overflow, spacing, contrast)

Added tests-pptx/test-agent.mjs for mock-based agent quality testing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Uses spire.presentation to render slides to PNG, then PIL to
create a labeled grid image. No LibreOffice dependency.

Usage: python3 tests-pptx/thumbnails.py tests-pptx/test.pptx

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…slides

After visual QA of generated slides, the main defect was text overflow
(content cut off at box edges). Added:

- Font size guidelines per element type (title, body, cards, tables)
- Content limits per slide type (max bullets, max columns)
- Space budget calculations (title zone, content zone)
- Mandatory get_slide_image verification after EVERY slide creation
- Bottom buffer rule (0.3" margin)

Reduced default font sizes in examples: bullets 18→16pt, tables 14→13pt.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…int slides

Visual QA showed bold labels merging into descriptions without spacing
(e.g., 'Machine LearningSystems that...'). Added explicit rules and
examples to all three PowerPoint prompt files (APP_PROMPT, AGENT, SKILL):

- Never merge bold label + description in one text run
- Use colon separator in same line OR indented sub-line
- Added WRONG/CORRECT code examples showing the issue and fix

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… PowerPoint

Visual QA round 2 showed slides 2 & 4 rendering '[object Object],[object Object]'
instead of text. Root cause: the nested text array syntax { text: [{...}, {...}] }
is not supported by PptxGenJS's addText API.

Replaced all examples with two safe patterns:
- Option A: Single string with colon separator ('Label: description')
- Option B: Bold heading + indented sub-line (indentLevel: 1)

Added explicit WRONG example showing the nested array anti-pattern.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Split the monolithic PowerPoint skill (239 lines) into focused skills:

- powerpoint (core): Tool routing, operating loop, always-on defaults
- powerpoint-deck-builder: Layout variety, content sizing, verification loops
- powerpoint-redesign: Template adaptation, shape manipulation, redesign workflows
- powerpoint-formatting: PptxGenJS rules, anti-patterns, correct code examples

Users can now toggle skills per task — deck creation gets sizing rules
while simple reads don't get bloated context. All skills are host-filtered
to powerpoint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
QA round 3 still showed bold labels merging into descriptions ('Machine
LearningSystems that...'). Root cause: the agent uses separate text runs
(bold + normal) which PptxGenJS renders without spacing.

Removed the indented sub-line option (Option B) from all prompts.
Only ONE pattern is now allowed: 'Label: Description' as a single string.
Added explicit anti-pattern example showing the separate runs bug.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…cription

QA round 4 showed Slide 2 overflow: agent wrote full sentences as bullet
descriptions instead of short phrases. Tightened rules across all prompts:

- Bullets: max 8 words (was 10), max 5 bullets (was 5-6)
- Label:Description pattern: description ≤ 6 words after colon
- New 'definition + bullets' combo limit: 2-line paragraph + 4 bullets
- Marked content limits as MANDATORY with warning
- 'Shorten the text' priority over shrinking fonts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
trsdn and others added 25 commits February 22, 2026 12:41
Major prompt overhaul across all PowerPoint skills:

Verification loop:
- Changed from 'recommended' to MANDATORY with checklist format
- Added per-slide loop algorithm: create → verify → fix → re-verify
- Added fix action table (issue → specific fix)
- Added minimum get_slide_image call counts (= number of slides)
- 'Do NOT move to next slide until current passes all checks'

Content limits:
- Definition + bullets: max 4 bullets (NOT 5) when intro exists
- German-language examples in ✅/❌ patterns
- Word-breaking fix actions: reduce columns (4→3) or shorten text

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
QA round 8: German compound words ('Medikamentenentwicklung', 22 chars)
break mid-word in 3-column layouts. Added:

- No word in a column should exceed 12 characters
- Explicit compound word → shorter synonym examples in fix table
- 'Visual clarity > terminological precision' principle
- Bottom text cut-off fix action

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removed excessive content limit rules (word counts, char limits, space
budgets). Kept the essential formatting rules (PptxGenJS anti-patterns)
and a compact font size table. The core improvement: a much clearer
Create → Verify → Fix loop that emphasizes 'look at it and fix what
you see' over memorizing rules.

APP_PROMPT: ~95 lines (was ~119)
AGENT.md: ~60 lines (was ~85)
deck-builder SKILL: ~70 lines (was ~136)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The agent does verification loops now but misses text cut off at the
bottom of text boxes. Added 'CHECK THE BOTTOM EDGE FIRST' as step 1
in the verification checklist across all prompts — this is where
overflow always happens and is easy to overlook.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The agent couldn't detect text overflow in small cards because the
image was only 320px wide (max 400px). At that resolution, cut-off
text at the bottom of cards is nearly invisible.

Changes:
- Default width: 320 → 800px
- Max width: 400 → 1200px
- Size warning threshold: 50KB → 200KB
- Updated description to emphasize overflow detection purpose

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tection

Instead of sending one large full-slide image, the agent can now request
specific regions: full, top, bottom, left, right. The 'bottom' region
captures the bottom half at 960px (high detail) and crops via Canvas,
keeping image size small while giving the agent a zoomed view of where
text overflow typically occurs.

- Added region parameter (enum: full/top/bottom/left/right)
- cropImage() uses Canvas to crop the captured PNG
- 'full' captures at 600px, regions at 960px (cropped = ~half the data)
- Auto-fallback to 400px if result still exceeds 150KB
- Updated all prompts to use get_slide_image(region: 'bottom') in
  the verification loop

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…4:3 dimensions

The agent was generating slides at 10"×7.5" (4:3 default) regardless
of the actual presentation format. On 16:9 presentations (13.33"×7.5"),
content only filled 75% of the slide width.

Changes:
- add_slide_from_code now reads pageSetup.slideWidth/Height and sets
  PptxGenJS layout to match (falls back to 10×7.5 on older API)
- get_presentation_overview now reports slide dimensions + aspect ratio
- Updated all prompts/skills to use dynamic widths instead of hardcoded
  w:9 / right≤9.5 (all examples now show 16:9 values with note to
  check get_presentation_overview for actual size)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…zoom

One tool call now returns 5 images: a 480px overview + 4 zoomed
quadrant crops from a 960px capture (top-left, top-right, bottom-left,
bottom-right). Each quadrant is 480×360px — high enough detail to
catch text overflow while keeping individual images small.

"detailed" is the new default. The agent inspects all 5 images in the
verification loop to catch issues anywhere on the slide.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Returning 5 base64 images in one tool result would exceed the Copilot
CLI output size limit. Instead, the verification loop now uses separate
calls: full overview + bottom-left/bottom-right quadrants for 2x zoom
where overflow occurs. Each call returns one image, staying well
within size limits.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Updated intro, diagram, features, prerequisites to reflect all 4 hosts
- Added tool counts: Excel ~83, PowerPoint 24, Word 35, Outlook 22
- Updated test counts to current (31 files, 276 unit tests)
- Noted E2E tests for non-Excel hosts are planned

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…y loop

Raised recommended font sizes (body 16-20pt, cards 14-16pt, tables
13-15pt, min 13pt). Added 'text too small' as explicit check in the
Create→Verify→Fix loop so the agent catches and fixes tiny text.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The user only sees tool calls in the UI. The agent now narrates each
step: which slide it's working on, what layout it chose, what it found
during verification, and what it's fixing. Examples in the user's
language keep it natural.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removed turnAnchor='top' from ThreadPrimitive.Viewport which was
pinning the scroll position to the top of each turn. Now the viewport
follows new content as it streams in, so the user can see progress
narration and tool results in real time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a multi-session architecture for PowerPoint deck creation:

- Planner session creates a structured JSON slide plan via submit_plan tool
- Worker sessions execute slides sequentially, each with a fresh context
- Automatic retry on worker failure (1 retry, then skip)
- Progress narration streams to chat UI (plan/slide status/errors)

New files:
- src/lib/session-factory.ts — runSubSession() helper
- src/tools/planner/index.ts — submit_plan tool + plan extraction
- src/services/ai/prompts/PLANNER_PROMPT.md — planning-only prompt
- src/services/ai/prompts/WORKER_PROMPT.md — single-slide worker prompt
- src/hooks/useDeckOrchestrator.ts — orchestrateDeck() function

Modified:
- src/hooks/useOfficeChat.ts — detects multi-slide requests, routes to
  orchestrator instead of single session. Exposes clientRef.

The orchestrator activates when: host=powerpoint AND prompt mentions
N slides/folien AND doesn't say 'this slide'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The submit_plan tool arguments weren't available in session events.
Now the tool handler captures the plan directly via a module-level
variable, and the orchestrator reads it via getLastPlan().

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fast mode (default): 3 slides per worker session — fewer sessions, faster
Deep mode: 1 slide per worker — maximum quality, full verify per slide

Triggered by keywords in prompt: 'deep', 'detail', 'qualit' → deep mode.
Otherwise defaults to fast mode.

10 slides: fast = 4 sessions (1 planner + 3 workers), deep = 11 sessions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fast = 1 planner + 1 worker session (all slides).
Deep = 1 planner + N worker sessions (1 slide each).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: add WorkIQ toggle and MCP tool integration

Add a one-click WorkIQ toggle in the ChatHeader that enables Microsoft 365
data access (emails, meetings, documents, Teams) via the WorkIQ MCP server.
Also adds full MCP tool integration supporting HTTP, SSE, and stdio transports.

Changes:
- Add WorkIQ toggle button (brain icon) to ChatHeader with visual state
- Add workiqEnabled setting to UserSettings with persistence
- Add built-in WORKIQ_MCP_SERVER constant (no manual mcp.json import needed)
- Add mcpClient.mjs server-side module for connecting to MCP servers
- Add stdio transport support (StdioClientTransport) for subprocess-based MCP
- Wire MCP servers into copilotProxy.mjs session.create with lifecycle cleanup
- Pass active MCP servers from browser to proxy via websocket-client
- Auto-inject WorkIQ when enabled in useOfficeChat hook
- Wire McpManagerDialog into ChatHeader for advanced MCP server management
- Update MCP config parser to accept stdio entries (command + args)
- Update tests for stdio support (276 tests passing)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: deduplicate WorkIQ when both toggle and manual import exist

Filter out any imported 'workiq' MCP server when the built-in toggle is
active to prevent duplicate server connections.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: add stdio command allowlist, fix race condition, add WorkIQ tests

- Add ALLOWED_STDIO_COMMANDS allowlist (npx, node, python, python3) to
  mcpClient.mjs — blocks arbitrary command execution via WebSocket
- Fix __pending__ race condition in copilotProxy.mjs by using unique
  temp keys instead of a static '__pending__' key
- Remove personal path (C:\Users\urstojki\...) from workiq-mcp.json
- Add 8 unit tests: toggleWorkiq (4), WORKIQ_MCP_SERVER constant (4)
- All 284 tests passing

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Torsten Mahr <torsten.mahr@gmail.com>
…#3)

- Add Word document orchestrator (planner→worker pattern, mirrors PowerPoint)
  - Deep-mode triggers: deep keywords, multi-section requests, doc creation
  - WORD_PLANNER_PROMPT.md + WORD_WORKER_PROMPT.md with verify checklist
  - submit_document_plan tool + wordPlanner.ts
- Add 3 Outlook skills: email-analysis, drafting, calendar
- Add 3 Word skills: formatting, document-builder, tables
- Add WorkIQ model dropdown in ChatHeader (separate model for WorkIQ sessions)
- Add sideload scripts: start:excel, start:word, start:powerpoint
- Improve prompt starters for all hosts
- Add *.md?raw type declaration for Vite raw imports
- Add docs/WORKIQ.md documenting WorkIQ integration and prerequisites
- Fix wordPlanner test: pass mock invocation to handler
- 47 new tests (wordDeepMode + wordPlanner)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…m PR #33

- Word: 25 new tools (paragraphs, tables, images, headers/footers, footnotes,
  content controls, hyperlinks, sections, bookmarks, formatting search)
- Outlook: 22 tools for email, calendar, contacts, drafts, search
- WorkIQ: Microsoft 365 data integration via MCP (toggleable, own model selector)
- Word orchestrator: planner-worker pattern (wordPlanner, useDocumentOrchestrator)
- PowerPoint deck orchestrator: useDeckOrchestrator hook
- New skills: outlook, word, powerpoint skill files with host targeting
- New agent: Outlook agent with frontmatter
- New prompts: WORD_PLANNER_PROMPT, WORD_WORKER_PROMPT, WORKER_PROMPT, PLANNER_PROMPT
- Updated ChatHeader: WorkIQ toggle + model selector + MCP button
- Updated settings: workiqEnabled, workiqModel persisted in Zustand store
- Updated useOfficeChat: WorkIQ MCP injection into active servers

Co-authored-by: Torsten <trsdn@users.noreply.github.com>
@sbroenne sbroenne merged commit edddccd into main Feb 26, 2026
3 checks passed
@sbroenne sbroenne deleted the feat/word-orchestrator-outlook-workiq branch February 26, 2026 17:40
@sbroenne sbroenne mentioned this pull request Feb 26, 2026
sbroenne added a commit that referenced this pull request Feb 26, 2026
Bumps version to **0.3.0**.

## What's new since v0.2.0

### ✨ New Features
- **Outlook host** — 22 tools (emails, calendar, contacts, folders,
attachments, search, flags, drafts), dedicated agent, 4 skills, manifest
(#45)
- **Word document orchestrator** — planner→worker pattern with deep/fast
modes, \submit_document_plan\ tool, Word expanded to 35 tools (#45)
- **PowerPoint expanded** — 24 tools, 4 new skills (deck-builder,
formatting, redesign, presentation), improved \get_slide_image\ with
region cropping (#45)
- **WorkIQ integration** — MCP stdio transport, workiqModel setting, UI
toggle in ChatHeader (#45)
- **MCP servers** — stdio/npx MCP server support + npm skill packages as
internal tools (#41)
- **Electron tray app** — system tray with single-instance lock,
production server, installer packaging (#43)
- **Session history** — persistent conversation history with restore
picker (#43)
- **Permissions flow** — interactive approve/deny permission UI (#43)
- **Auto-scroll** — chat thread stays pinned to newest content (#43)
- **Thinking indicator** — dynamic text from \ eport_intent\ and tool
execution phase (#34, #37)
- **Custom agents & skills** — ZIP import/export, management dialogs
(#29, #38)
- **Host-scoped skills** — skills filtered by current Office host (#40)

### 🔒 Security
- bump rollup 4.58.0 → 4.59.0 (Arbitrary File Write CVE) (#46)
- bump hono 4.12.0 → 4.12.3 (Auth Bypass CVE) (#46)

### 🛠 Other
- Added \start:desktop:excel/ppt/word/outlook\ convenience scripts
- Branch protection + squash-merge-only policy enforced (#44)
- 458/458 integration tests passing; E2E: Excel ~187, PPT ~13, Word ~12,
Outlook ~9

Co-authored-by: Stefan Broenner <stefan.broenner@microsoft.comm>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants