Artur Mukhamadiev 71833d83d8 feat(skills&butler) DevTools MCP Server Example for user
:Release Notes:
- Added skills examples for MS Teams work
- Added agent file "browser-butler" for actual work execution

:Detailed Notes:
-

:Testing Performed:
-

:QA Notes:
- Tested with claude code and opencode

:Issues Addressed:
- Done for Chrome DevTools MCP Server seminar
2026-06-27 19:13:58 +03:00

95 lines
3.5 KiB
Markdown

---
name: ms-teams-multiline-typing
description: Use when typing a multiline message into the MS Teams chat compose box via Chrome DevTools MCP. Covers the Shift+Enter newline pattern and why literal \n fails. Use ONLY when the user asks to type or compose a multi-paragraph message in MS Teams.
---
# MS Teams multiline typing
How to insert line breaks when composing a message in Microsoft Teams via
Chrome DevTools MCP. Verified empirically against the live Teams web app.
## The input element
- `<div role="textbox" contenteditable="true">` — a CKEditor instance
wrapped in FluentUI. State lives in CKEditor's model, not the DOM.
- Exposed in the a11y snapshot as `textbox "Type a message" multiline`.
## Plain text (single line)
```
chrome-devtools_type_text text: "Hello"
```
Works as expected — text is inserted into the current `<p>`.
## Multiline text — REQUIRED pattern
CKEditor **rejects** raw `\n` characters. A single `type_text` call with an
embedded newline silently drops the **entire** input (not just the
newline); the editor stays empty. Confirmed empirically:
| Input method | Result |
| --- | --- |
| `type_text "A\nB\nC"` | editor empty, nothing inserted |
| `type_text "A"` then `Shift+Enter` then `type_text "B"` | two `<p>` blocks inserted |
Therefore multiline messages MUST be built by alternating `type_text` and
`Shift+Enter`:
```
chrome-devtools_type_text text: "Line 1"
chrome-devtools_press_key key: "Shift+Enter"
chrome-devtools_type_text text: "Line 2"
chrome-devtools_press_key key: "Shift+Enter"
chrome-devtools_type_text text: "Line 3"
```
Each `Shift+Enter` dispatches a real `KeyboardEvent('keydown', {key:
'Enter', shiftKey: true})`, which CKEditor's keydown handler intercepts
to execute `enterShift` and insert a new `<p>` into the model.
## Why `\n` fails (mechanism)
CKEditor routes text insertion through its model via `beforeinput`/`input`
events. A raw `\n` does not map to any `inputType` (`insertParagraph` and
`insertLineBreak` are the valid ones, both triggered by keystrokes, not by
literal newline chars). When the handler can't route the input, the entire
insert is rejected — not partially applied. This is stricter than a plain
`<textarea>`, where `fill` with `\n` works fine.
## Verifying the draft
```js
() => {
const e = document.querySelector('[role="textbox"]');
return { innerText: e.innerText, pCount: e.querySelectorAll('p').length };
}
```
The a11y snapshot will also show `paragraph` children with `LineBreak`
nodes between them.
## Do NOT
- Do not use `chrome-devtools_fill` with `\n` on the Teams editor — it
fails silently for the same reason as `type_text` with `\n`.
- Do not mutate `innerHTML` directly — Teams enforces TrustedHTML policy
and the assignment throws. Even if it didn't, React/CKEditor state would
desync from the DOM and the Send button would stay disabled.
## Generalizing to other chat apps
Same `type_text` + `Shift+Enter` pattern works for Slack, WhatsApp Web,
and Gosuslugi chat — they are all contenteditable under the hood. What
differs:
| App | Newline shortcut | Send shortcut |
| --- | --- | --- |
| MS Teams | `Shift+Enter` | `Ctrl+Enter` (or click Send) |
| Slack | `Shift+Enter` | `Enter` (configurable) |
| WhatsApp Web | `Shift+Enter` | `Enter` |
| Gosuslugi | `Enter` (if `<textarea>`) / `Shift+Enter` (if contenteditable) | Send button click |
Always probe the element type first: a true `<textarea>` accepts `\n` in
`fill` directly and needs no `Shift+Enter`; a `contenteditable` requires
the keystroke approach.