@patimweb/pi-teams 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +412 -0
  3. package/index.ts +1 -0
  4. package/package.json +61 -0
  5. package/prompts/teams-catch-up.md +24 -0
  6. package/prompts/teams-channel-digest.md +23 -0
  7. package/prompts/teams-doctor.md +21 -0
  8. package/prompts/teams-meeting-prep.md +22 -0
  9. package/prompts/teams-standup.md +21 -0
  10. package/prompts/teams-triage.md +22 -0
  11. package/skills/teams-collaboration/SKILL.md +143 -0
  12. package/src/auth/client-credentials.ts +72 -0
  13. package/src/auth/device-code.ts +276 -0
  14. package/src/auth/index.ts +105 -0
  15. package/src/auth/jwt.ts +50 -0
  16. package/src/auth/token-store.ts +156 -0
  17. package/src/config/index.ts +685 -0
  18. package/src/config/scope.ts +272 -0
  19. package/src/extension/index.ts +336 -0
  20. package/src/graph/calendar.ts +165 -0
  21. package/src/graph/chats.ts +159 -0
  22. package/src/graph/client.ts +234 -0
  23. package/src/graph/mappers.ts +268 -0
  24. package/src/graph/me.ts +80 -0
  25. package/src/graph/messages.ts +383 -0
  26. package/src/graph/presence.ts +160 -0
  27. package/src/graph/search.ts +111 -0
  28. package/src/graph/teams.ts +271 -0
  29. package/src/safety/audit.ts +57 -0
  30. package/src/safety/index.ts +186 -0
  31. package/src/status.ts +90 -0
  32. package/src/tools/resolve.ts +138 -0
  33. package/src/tools/shared.ts +124 -0
  34. package/src/tools/teams-accounts.ts +169 -0
  35. package/src/tools/teams-create-channel.ts +89 -0
  36. package/src/tools/teams-create-chat.ts +112 -0
  37. package/src/tools/teams-delete-message.ts +114 -0
  38. package/src/tools/teams-doctor.ts +182 -0
  39. package/src/tools/teams-find-user.ts +64 -0
  40. package/src/tools/teams-inbox.ts +142 -0
  41. package/src/tools/teams-list-channels.ts +62 -0
  42. package/src/tools/teams-list-chats.ts +74 -0
  43. package/src/tools/teams-list-files.ts +54 -0
  44. package/src/tools/teams-list-members.ts +72 -0
  45. package/src/tools/teams-list-teams.ts +65 -0
  46. package/src/tools/teams-login.ts +199 -0
  47. package/src/tools/teams-meetings.ts +342 -0
  48. package/src/tools/teams-permissions.ts +169 -0
  49. package/src/tools/teams-presence.ts +216 -0
  50. package/src/tools/teams-react.ts +109 -0
  51. package/src/tools/teams-read-channel.ts +75 -0
  52. package/src/tools/teams-read-chat.ts +73 -0
  53. package/src/tools/teams-read-thread.ts +88 -0
  54. package/src/tools/teams-search-messages.ts +71 -0
  55. package/src/tools/teams-send-channel-message.ts +250 -0
  56. package/src/tools/teams-send-chat-message.ts +152 -0
  57. package/src/tools/teams-setup.ts +245 -0
  58. package/src/tools/teams-status.ts +73 -0
  59. package/src/tools/tool-names.ts +30 -0
  60. package/src/types.ts +192 -0
  61. package/src/utils/errors.ts +133 -0
  62. package/src/utils/formatting.ts +356 -0
  63. package/tsconfig.json +16 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Patrick Weppelmann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,412 @@
1
+ # pi-teams
2
+
3
+ Microsoft Teams integration for the [pi coding agent](https://github.com/earendil-works/pi).
4
+
5
+ pi acts **as you**: it reads what you can read, and anything it sends comes
6
+ from your account, in your name, in the right thread. Multiple Teams accounts
7
+ and multiple company tenants live side by side, and a configuration file
8
+ decides exactly which teams, channels, chats and people pi may touch.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ # From npm
14
+ pi install npm:@patimweb/pi-teams
15
+
16
+ # From a local checkout during development
17
+ pi install /path/to/pi-teams
18
+ ```
19
+
20
+ ## Quick start
21
+
22
+ 1. **Register an app in Entra ID** (once per organization — see below).
23
+ 2. **Configure the account:**
24
+ ```
25
+ teams_setup:
26
+ name: work
27
+ tenantId: contoso.onmicrosoft.com
28
+ clientId: <application (client) ID>
29
+ setDefault: true
30
+ ```
31
+ 3. **Sign in:** run `/teams-login`. pi shows a code and a URL; open it, enter
32
+ the code, sign in as yourself.
33
+ 4. **Check it works:** `/teams-status`, then `/teams-inbox`.
34
+
35
+ ---
36
+
37
+ ## Entra ID app registration
38
+
39
+ pi signs in with the OAuth 2.0 **device authorization grant**, so it never sees
40
+ your password and your MFA works normally.
41
+
42
+ ### 1. Create the registration
43
+
44
+ Entra admin center → **App registrations** → **New registration**
45
+
46
+ | Field | Value |
47
+ |-------|-------|
48
+ | Name | `pi-teams` (anything you like) |
49
+ | Supported account types | **Accounts in any organizational directory (multitenant)** — required if pi should also reach customer or guest tenants. Single tenant is fine for one company. |
50
+ | Redirect URI | leave empty |
51
+
52
+ Note the **Application (client) ID** and **Directory (tenant) ID**.
53
+
54
+ ### 2. Enable public client flows
55
+
56
+ **Authentication** → *Advanced settings* → **Allow public client flows** →
57
+ **Yes**.
58
+
59
+ Without this, sign-in fails with `AADSTS7000218`.
60
+
61
+ ### 3. Add delegated permissions
62
+
63
+ **API permissions** → **Add a permission** → **Microsoft Graph** →
64
+ **Delegated permissions**:
65
+
66
+ | Permission | Needed for |
67
+ |-----------|-----------|
68
+ | `User.Read`, `User.ReadBasic.All` | identity, looking colleagues up |
69
+ | `Team.ReadBasic.All`, `Channel.ReadBasic.All` | listing teams and channels |
70
+ | `ChannelMessage.Read.All` | reading channel messages |
71
+ | `ChannelMessage.Send` | posting and replying in channels |
72
+ | `ChannelMember.Read.All` | channel member lists |
73
+ | `Chat.ReadWrite` | reading chats, creating chats |
74
+ | `ChatMessage.Send` | sending chat messages |
75
+ | `Presence.ReadWrite`, `Presence.Read.All` | your status, colleagues' availability |
76
+ | `Calendars.ReadWrite` | reading and creating calendar events |
77
+ | `OnlineMeetings.ReadWrite` | Teams meeting links |
78
+ | `Files.Read.All`, `Sites.Read.All` | channel files |
79
+ | `offline_access` | staying signed in |
80
+
81
+ Some of these require **admin consent**. Click *Grant admin consent* if you
82
+ can, or ask an administrator. `teams_doctor` reports exactly which scopes were
83
+ granted and which were not, so you never have to guess from a 403.
84
+
85
+ To request fewer permissions, set `scopes` on the account — see below.
86
+
87
+ ### 4. Guest and customer tenants
88
+
89
+ For a tenant that is not your own:
90
+
91
+ - the registration must be **multitenant**,
92
+ - your account must be a guest in that tenant,
93
+ - an administrator there consents to the app once.
94
+
95
+ Then add it as a tenant beneath your account (`parentAccount`) and sign in
96
+ again against it.
97
+
98
+ ---
99
+
100
+ ## Acting as a user vs. app-only
101
+
102
+ | | `device-code` (default) | `client-credentials` |
103
+ |---|---|---|
104
+ | Identity | you | the application |
105
+ | Sign-in | once, interactive | none |
106
+ | Reading chats/channels | yes | only via protected APIs |
107
+ | **Sending messages** | **yes** | **no** — refused with an explanation |
108
+ | Presence, calendar | yes | partially |
109
+
110
+ Microsoft Graph only permits app-only writes to chats and channels for
111
+ migration scenarios (`Teamwork.Migrate.All`), so pi-teams refuses those calls
112
+ up front instead of letting them fail deep inside a Graph request. Use
113
+ `client-credentials` for unattended read-only jobs, `device-code` for
114
+ everything that speaks in your name.
115
+
116
+ ---
117
+
118
+ ## Configuration
119
+
120
+ Everything lives in `~/.pi/agent/pi-teams.json` (mode `0600`, created from a
121
+ template on first run). `teams_setup` writes the same file — use whichever you
122
+ prefer.
123
+
124
+ ```json
125
+ {
126
+ "accounts": [
127
+ {
128
+ "name": "work",
129
+ "displayName": "NeoImpulse",
130
+ "tenantId": "neoimpulse.onmicrosoft.com",
131
+ "clientId": "00000000-0000-0000-0000-000000000000",
132
+ "authMode": "device-code",
133
+ "safetyLevel": "confirm",
134
+ "permissions": {
135
+ "read": {
136
+ "teams": { "allow": ["*"] },
137
+ "chats": { "allow": ["*"] }
138
+ },
139
+ "write": {
140
+ "channels": {
141
+ "allow": ["Engineering/*", "Project Alpha/General"],
142
+ "deny": ["*/Announcements"]
143
+ },
144
+ "chats": { "allow": ["*"] },
145
+ "people": { "deny": ["ceo@neoimpulse.de"] }
146
+ }
147
+ },
148
+ "tenants": [
149
+ {
150
+ "name": "customer-alpha",
151
+ "tenantId": "customeralpha.onmicrosoft.com",
152
+ "safetyLevel": "readonly",
153
+ "permissions": {
154
+ "read": { "channels": { "allow": ["Project Alpha/*"] } }
155
+ }
156
+ }
157
+ ]
158
+ },
159
+ {
160
+ "name": "private",
161
+ "tenantId": "othercompany.onmicrosoft.com",
162
+ "clientId": "11111111-1111-1111-1111-111111111111",
163
+ "safetyLevel": "open"
164
+ }
165
+ ],
166
+ "defaultAccount": "work",
167
+ "safetyLevel": "confirm",
168
+ "maxMessages": 25,
169
+ "audit": true
170
+ }
171
+ ```
172
+
173
+ ### Accounts and tenants
174
+
175
+ - An **account** is a Teams identity you sign in as. Each has its own saved
176
+ session.
177
+ - A **tenant** beneath an account is another directory that identity reaches:
178
+ a customer, a subsidiary, a guest tenant. It gets its own sign-in, its own
179
+ safety level and its own rules.
180
+
181
+ Every tool takes `account` and `tenant`:
182
+
183
+ ```yaml
184
+ teams_send_channel_message:
185
+ account: work
186
+ tenant: customer-alpha
187
+ channel: "Project Alpha/General"
188
+ body: "Sprint review moved to Thursday."
189
+ ```
190
+
191
+ ### Safety levels
192
+
193
+ | Level | Effect |
194
+ |-------|--------|
195
+ | `open` | writes go through without asking |
196
+ | `confirm` | every write shows a confirmation with the destination and the exact text (**default**) |
197
+ | `readonly` | writes are blocked entirely |
198
+
199
+ Set globally, per account, or per tenant — the most specific setting wins. So
200
+ your own company can be `confirm` while a customer tenant stays `readonly`.
201
+
202
+ ### Scope rules
203
+
204
+ Rules exist per **category** (`teams`, `channels`, `chats`, `people`) and per
205
+ **mode** (`read`, `write`). Category keys written directly in the block apply
206
+ to both modes; a `read` or `write` block refines one of them.
207
+
208
+ ```json
209
+ "permissions": {
210
+ "channels": { "deny": ["*/Announcements"] },
211
+ "write": { "channels": { "allow": ["Engineering/*"] } }
212
+ }
213
+ ```
214
+
215
+ - **`deny` accumulates** across global → account → tenant and always wins.
216
+ - **`allow` narrows**: the most specific level that defines one wins. Nothing
217
+ configured means everything the signed-in user can reach.
218
+ - Patterns are case-insensitive globs: `*` matches any run of characters
219
+ (including `/`), `?` matches one.
220
+ - A target matches if **any** of its identifiers does: channels match on
221
+ `Team/Channel`, their name or their ID; chats match on topic, participant
222
+ names and e-mail addresses; people match on name, UPN and e-mail.
223
+
224
+ Check a rule without touching anything:
225
+
226
+ ```yaml
227
+ teams_permissions:
228
+ action: test
229
+ category: channels
230
+ mode: write
231
+ target: "Engineering/Announcements"
232
+ ```
233
+
234
+ ### Other settings
235
+
236
+ | Key | Default | Meaning |
237
+ |-----|---------|---------|
238
+ | `defaultAccount` | first account | account used when a tool omits `account` |
239
+ | `maxMessages` | `25` | default page size for message listings |
240
+ | `audit` | `true` | append every write to `~/.pi/agent/pi-teams-audit.jsonl` |
241
+ | `scopes` | see above | override the requested Graph scopes per account/tenant |
242
+ | `graphBaseUrl` / `authorityHost` | Microsoft public cloud | sovereign cloud endpoints |
243
+
244
+ ---
245
+
246
+ ## Tools
247
+
248
+ ### Session and configuration
249
+
250
+ | Tool | Description |
251
+ |------|-------------|
252
+ | `teams_setup` | Write an account or tenant to the config file |
253
+ | `teams_login` | Sign in as yourself (device code flow) |
254
+ | `teams_logout` | Remove a saved session |
255
+ | `teams_accounts` | List accounts, switch the default, change a safety level, delete |
256
+ | `teams_status` | Which account is active, who pi acts as, what it may do |
257
+ | `teams_permissions` | Show, test or change the allow/deny rules |
258
+ | `teams_doctor` | Diagnose config, sign-in, consent and connectivity |
259
+
260
+ ### Reading
261
+
262
+ | Tool | Description |
263
+ |------|-------------|
264
+ | `teams_inbox` | Chats with new messages plus recent mentions of you |
265
+ | `teams_list_chats` | Recent chats with a preview of the last message |
266
+ | `teams_read_chat` | Messages of one chat |
267
+ | `teams_list_teams` | Teams you belong to |
268
+ | `teams_list_channels` | Channels of a team |
269
+ | `teams_read_channel` | Posts in a channel |
270
+ | `teams_read_thread` | One thread: opener plus every reply |
271
+ | `teams_search_messages` | Full-text search across chats and channels |
272
+ | `teams_list_members` | Members of a team or channel |
273
+ | `teams_find_user` | Directory lookup by name, e-mail or UPN |
274
+ | `teams_list_files` | Files in a channel's SharePoint folder |
275
+ | `teams_get_presence` | Your status, a colleague's, or a whole chat's |
276
+ | `teams_list_meetings` | Calendar events and meetings in a range |
277
+ | `teams_get_meeting` | One meeting in full |
278
+
279
+ ### Writing
280
+
281
+ | Tool | Description |
282
+ |------|-------------|
283
+ | `teams_send_chat_message` | Send a chat message as you |
284
+ | `teams_create_chat` | Start a 1:1 or group chat, optionally with the first message |
285
+ | `teams_send_channel_message` | Post in a channel as you |
286
+ | `teams_reply_channel_message` | Reply inside an existing thread |
287
+ | `teams_react` | Add or remove an emoji reaction |
288
+ | `teams_delete_message` | Soft-delete (or restore) a message you sent |
289
+ | `teams_create_channel` | Add a channel to a team |
290
+ | `teams_set_presence` | Set your Teams status |
291
+ | `teams_set_status_message` | Set the note under your name |
292
+ | `teams_create_meeting` | Schedule a Teams meeting with invitations |
293
+ | `teams_update_meeting` | Change a meeting you organize |
294
+ | `teams_cancel_meeting` | Cancel a meeting |
295
+
296
+ ## Commands
297
+
298
+ | Command | Description |
299
+ |---------|-------------|
300
+ | `/teams-status` | Show the connection and permissions |
301
+ | `/teams-login` | Start the device code sign-in |
302
+ | `/teams-inbox` | What needs your attention right now |
303
+ | `/teams-permissions` | What pi may and may not do |
304
+ | `/teams-doctor` | Diagnose the setup |
305
+
306
+ ## Prompts
307
+
308
+ | Prompt | Description |
309
+ |--------|-------------|
310
+ | `/teams-catch-up` | Summarize what happened while you were away |
311
+ | `/teams-triage` | Work through unanswered messages one by one |
312
+ | `/teams-channel-digest` | Decisions, open questions and action items in a channel |
313
+ | `/teams-standup` | Draft and post a standup update |
314
+ | `/teams-meeting-prep` | Context and talking points for your next meeting |
315
+ | `/teams-doctor` | Guided troubleshooting |
316
+
317
+ ---
318
+
319
+ ## Addressing things
320
+
321
+ **Channels** — a `Team/Channel` path, or `team` and `channel` separately.
322
+ Names resolve case-insensitively; an ambiguous name is reported, never guessed.
323
+
324
+ ```yaml
325
+ teams_read_channel:
326
+ channel: "Engineering/General"
327
+ limit: 20
328
+ ```
329
+
330
+ **Chats** — an ID, a group chat topic, or a participant's name or e-mail. If
331
+ more than one chat matches, the tool lists the candidates instead of picking
332
+ one.
333
+
334
+ ```yaml
335
+ teams_send_chat_message:
336
+ chat: "anna@contoso.com"
337
+ body: "Running five minutes late."
338
+ ```
339
+
340
+ **Mentions** — pass `mentions` and write `@Display Name` in the body where the
341
+ mention belongs:
342
+
343
+ ```yaml
344
+ teams_send_channel_message:
345
+ channel: "Engineering/General"
346
+ body: "@Anna Schmidt the pipeline is green again."
347
+ mentions: ["anna@contoso.com"]
348
+ ```
349
+
350
+ ---
351
+
352
+ ## Files pi writes
353
+
354
+ | File | Contents | Mode |
355
+ |------|----------|------|
356
+ | `~/.pi/agent/pi-teams.json` | accounts, tenants, safety levels, scope rules | `0600` |
357
+ | `~/.pi/agent/pi-teams-tokens.json` | access and refresh tokens per account+tenant | `0600` |
358
+ | `~/.pi/agent/pi-teams-audit.jsonl` | one line per write: when, who, where, what | `0600` |
359
+
360
+ Both the config and the token cache are written through a private temp file and
361
+ an atomic rename, so an interrupted write cannot truncate them. To revoke
362
+ pi's access entirely, run `teams_logout` with `all: true` and remove the app's
363
+ consent in Entra ID.
364
+
365
+ ## Architecture
366
+
367
+ Data-oriented: plain immutable data, I/O at the edges, pure functions in the
368
+ middle.
369
+
370
+ - **`src/types.ts`** — domain data as plain interfaces. No behavior.
371
+ - **`src/config/index.ts`** — accounts, tenants, the safety cascade, persistence.
372
+ - **`src/config/scope.ts`** — allow/deny matching. Pure, and the most heavily
373
+ tested module in the package.
374
+ - **`src/auth/`** — device code flow, client credentials, token cache, JWT claims.
375
+ - **`src/graph/client.ts`** — fetch wrapper: bearer token, paging, throttling.
376
+ - **`src/graph/*.ts`** — one module per resource area, returning domain types.
377
+ - **`src/graph/mappers.ts`** — Graph JSON → domain types. Pure.
378
+ - **`src/utils/formatting.ts`** — domain types → display strings. Pure.
379
+ - **`src/safety/`** — the three gates and the audit log.
380
+ - **`src/tools/`** — one module per tool.
381
+ - **`src/extension/index.ts`** — registration, commands, the `tool_call` interceptor.
382
+
383
+ ## Development
384
+
385
+ ```bash
386
+ npm install
387
+ npm run typecheck
388
+ npm test
389
+ ```
390
+
391
+ Tests cover the pure logic — scope matching, the config cascade, message body
392
+ construction, HTML flattening, the safety gates — and run without a tenant or
393
+ a network connection.
394
+
395
+ ## Troubleshooting
396
+
397
+ | Symptom | Cause and fix |
398
+ |---------|---------------|
399
+ | `AADSTS7000218` | "Allow public client flows" is off in the app registration |
400
+ | `AADSTS65001` | Consent missing — sign in again, or have an admin consent |
401
+ | `AADSTS50020` | The account is not a member/guest of that tenant, or the app is single-tenant |
402
+ | "Not signed in" | Run `teams_login`; the refresh token may have been revoked |
403
+ | "Blocked by configuration" | Your own scope rules. `teams_permissions action: test` shows which rule |
404
+ | "cannot run on an app-only token" | Set `authMode: "device-code"` and run `teams_login` |
405
+ | 403 on channel messages | `ChannelMessage.Read.All` / `ChannelMessage.Send` not consented |
406
+ | Throttled | Graph rate limit; the client retries with back-off, then reports it |
407
+
408
+ Run `teams_doctor` first — it checks all of the above at once.
409
+
410
+ ## License
411
+
412
+ MIT
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from "./src/extension/index.ts";
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@patimweb/pi-teams",
3
+ "version": "1.0.0",
4
+ "description": "Microsoft Teams integration for pi coding agent — acts fully as the signed-in user across multiple accounts and tenants: chats, channels, meetings, presence, with configurable guardrails",
5
+ "keywords": [
6
+ "pi-package",
7
+ "microsoft-teams",
8
+ "teams",
9
+ "microsoft-graph",
10
+ "pi-extension"
11
+ ],
12
+ "author": "Patrick Weppelmann",
13
+ "license": "MIT",
14
+ "type": "module",
15
+ "engines": {
16
+ "node": ">=22.0.0"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/Smotherer007/pi-teams.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/Smotherer007/pi-teams/issues"
24
+ },
25
+ "scripts": {
26
+ "build": "echo 'No build step defined'",
27
+ "test": "node scripts/test.mjs",
28
+ "test:watch": "node scripts/test.mjs --watch",
29
+ "typecheck": "tsc --noEmit"
30
+ },
31
+ "dependencies": {
32
+ "typebox": "^1.2.8"
33
+ },
34
+ "peerDependencies": {
35
+ "@earendil-works/pi-coding-agent": ">=0.70.0",
36
+ "typebox": ">=1.0.0"
37
+ },
38
+ "devDependencies": {
39
+ "@earendil-works/pi-coding-agent": "^0.85.1",
40
+ "@earendil-works/pi-tui": "^0.80.3",
41
+ "@semantic-release/git": "^10.0.0",
42
+ "@types/node": "^22.0.0",
43
+ "semantic-release": "^25.0.0",
44
+ "typescript": "^5.7.0"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "pi": {
50
+ "extensions": [
51
+ "./index.ts"
52
+ ],
53
+ "skills": [
54
+ "./skills"
55
+ ],
56
+ "prompts": [
57
+ "./prompts"
58
+ ],
59
+ "image": "https://raw.githubusercontent.com/Smotherer007/pi-teams/main/screenshot.png"
60
+ }
61
+ }
@@ -0,0 +1,24 @@
1
+ ---
2
+ description: Summarize what happened in Microsoft Teams while you were away
3
+ argument-hint: "[hours, e.g. 24]"
4
+ ---
5
+ Catch me up on Microsoft Teams.
6
+
7
+ 1. Run `teams_inbox` with `hours` set to $@ (default 24 if nothing was given).
8
+
9
+ 2. For every chat with new messages, run `teams_read_chat` to read the actual
10
+ messages — the preview alone is not enough to judge whether something needs
11
+ an answer.
12
+
13
+ 3. For every mention, run `teams_read_thread` (channel) or `teams_read_chat`
14
+ (chat) to get the surrounding context.
15
+
16
+ 4. Summarize as:
17
+ - **Needs a reply from me** — who is waiting, on what, and since when
18
+ - **FYI** — decisions, announcements and progress I should know about
19
+ - **Noise** — one line, just the count
20
+
21
+ Keep each item to one or two sentences and name the people involved.
22
+
23
+ 5. For anything in "Needs a reply", propose a short draft reply, but do not
24
+ send anything. Ask me which drafts to send.
@@ -0,0 +1,23 @@
1
+ ---
2
+ description: Summarize what happened in a Teams channel
3
+ argument-hint: "<Team/Channel> [days]"
4
+ ---
5
+ Summarize a Microsoft Teams channel: $@
6
+
7
+ 1. Resolve the channel with `teams_read_channel` (a `Team/Channel` path works
8
+ directly). If no channel was named, ask which one — do not guess.
9
+
10
+ 2. Read the recent posts. For every post that has replies, run
11
+ `teams_read_thread` so the summary reflects the discussion, not just the
12
+ opening message.
13
+
14
+ 3. Produce:
15
+ - **Decisions** — what was decided, by whom
16
+ - **Open questions** — what is still unanswered, and who asked
17
+ - **Action items** — who owes what, with any dates mentioned
18
+ - **Notable** — anything else worth knowing
19
+
20
+ 4. Reference the people by name and include the `messageId` for anything I
21
+ might want to reply to.
22
+
23
+ Do not post anything in the channel.
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Diagnose and fix the Microsoft Teams connection
3
+ ---
4
+ Something is wrong with my Teams connection.
5
+
6
+ 1. Run `teams_doctor` for every configured account.
7
+
8
+ 2. Explain each problem in plain language, and say who can fix it — me or a
9
+ tenant administrator. In particular:
10
+ - missing consent → name the exact Graph scope and what it is needed for
11
+ - "Allow public client flows" disabled → the setting is in Entra ID →
12
+ App registrations → Authentication
13
+ - expired or revoked sign-in → I need to run `teams_login` again
14
+ - a guest tenant that rejects the sign-in → the app registration must be
15
+ multi-tenant and I must be invited to that tenant
16
+
17
+ 3. Run `teams_permissions` with `action: "show"` and tell me, in one short
18
+ paragraph, what you are currently allowed to do and what you are not.
19
+
20
+ 4. Propose the concrete next step. Do not change my configuration without
21
+ asking first.
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Prepare for your next Teams meeting
3
+ argument-hint: "[meeting subject or 'next']"
4
+ ---
5
+ Prepare me for a Teams meeting: $@
6
+
7
+ 1. Run `teams_list_meetings` to find the meeting. If nothing was specified,
8
+ take the next one starting from now. Show me which meeting you picked.
9
+
10
+ 2. Run `teams_get_meeting` for the full details — attendees, agenda, join link.
11
+
12
+ 3. Search Teams for context with `teams_search_messages`: the meeting subject,
13
+ and the names of the attendees. Read the relevant threads with
14
+ `teams_read_thread` or `teams_read_chat`.
15
+
16
+ 4. Give me:
17
+ - **When and who** — time, join link, attendees and their roles if visible
18
+ - **Context** — what has been discussed about this recently, with dates
19
+ - **Open items** — questions left unanswered in the threads
20
+ - **Suggested talking points** — three to five, grounded in what you read
21
+
22
+ Do not message anyone.
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Draft and post a standup update to a Teams channel
3
+ argument-hint: "<Team/Channel>"
4
+ ---
5
+ Help me post a standup update to: $@
6
+
7
+ 1. If no channel was given, ask for one.
8
+
9
+ 2. Read the channel's last few posts with `teams_read_channel` so the update
10
+ fits what the team has been discussing, and so I do not repeat something
11
+ that was already said.
12
+
13
+ 3. Ask me for anything you cannot know: what I did yesterday, what I am doing
14
+ today, and what is blocking me. Do not invent progress, and do not carry
15
+ over items from an old update as if they were new.
16
+
17
+ 4. Draft the update in my voice — short, plain, no headings unless the channel
18
+ uses them. Match the format of the previous standups in that channel.
19
+
20
+ 5. Show me the draft and the exact destination channel. Only after I approve,
21
+ post it with `teams_send_channel_message`.
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Work through unanswered Teams messages one by one
3
+ argument-hint: "[hours]"
4
+ ---
5
+ Triage my Microsoft Teams messages from the last $@ hours (default 24).
6
+
7
+ 1. Run `teams_inbox` to find what is waiting.
8
+
9
+ 2. For each item, read enough context (`teams_read_chat` or
10
+ `teams_read_thread`) to judge it, then classify it as:
11
+ - **Answer now** — a short reply unblocks someone
12
+ - **Needs me** — requires a decision or information only I have
13
+ - **Delegate** — someone else should handle it; say who
14
+ - **Ignore** — no action needed
15
+
16
+ 3. Present the list as a table: who, what, classification, and the chat or
17
+ channel it lives in.
18
+
19
+ 4. For everything in "Answer now", draft a reply in my voice. Show me all the
20
+ drafts together, then send only the ones I approve, one tool call each.
21
+
22
+ 5. Do not react, reply or change anything before I approve it.