ask-marcel-office-cli 1.0.0 → 1.4.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.
- package/README.md +119 -394
- package/dist/cli.js +4183 -1772
- package/dist/commands.json +309 -104
- package/dist/domain/iso-datetime.d.ts +30 -0
- package/dist/index.js +3780 -1712
- package/dist/infra/auth.d.ts +30 -0
- package/dist/infra/browser-auth.d.ts +75 -10
- package/dist/infra/graph-client.d.ts +38 -0
- package/dist/infra/network-error.d.ts +9 -0
- package/dist/presenter/error-hints.d.ts +41 -0
- package/dist/presenter/output.d.ts +2 -1
- package/dist/use-cases/commands/build-command.d.ts +30 -8
- package/dist/use-cases/commands/command-types.d.ts +12 -1
- package/dist/use-cases/commands/convert-mail-to-markdown.d.ts +4 -0
- package/dist/use-cases/commands/docs-render.d.ts +4 -2
- package/dist/use-cases/commands/docs.d.ts +44 -1
- package/dist/use-cases/commands/{download-drive-item-version-as-markdown.d.ts → download-drive-item-version.d.ts} +5 -0
- package/dist/use-cases/commands/fetch-raw-bytes.d.ts +1 -1
- package/dist/use-cases/commands/find-chats-with-user.d.ts +10 -0
- package/dist/use-cases/commands/get-chat.d.ts +1 -5
- package/dist/use-cases/commands/get-excel-used-range.d.ts +7 -2
- package/dist/use-cases/commands/get-teams-chat-message.d.ts +9 -0
- package/dist/use-cases/commands/iso-datetime-schema.d.ts +21 -0
- package/dist/use-cases/commands/link-shape.d.ts +13 -0
- package/dist/use-cases/commands/list-calendar-view-delta.d.ts +2 -2
- package/dist/use-cases/commands/list-teams-chat-history.d.ts +16 -0
- package/dist/use-cases/commands/list-teams-chat-messages.d.ts +8 -0
- package/dist/use-cases/commands/list-teams-chats-with-messages.d.ts +9 -0
- package/dist/use-cases/commands/resolve-calendar-link.d.ts +8 -0
- package/dist/use-cases/commands/resolve-drive-share-link.d.ts +8 -0
- package/dist/use-cases/commands/resolve-mail-link.d.ts +8 -0
- package/dist/use-cases/commands/resolve-teams-link.d.ts +8 -0
- package/dist/use-cases/commands/version-id.d.ts +7 -6
- package/docs/COMMANDS.md +243 -0
- package/docs/USAGE.md +249 -0
- package/docs/commands.json +309 -104
- package/package.json +3 -1
- package/dist/use-cases/commands/download-drive-item-version-as-pdf.d.ts +0 -12
- package/dist/use-cases/commands/download-drive-item-version-content.d.ts +0 -12
package/dist/commands.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "ask-marcel-office-cli",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"generatedAt": "2026-05-
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"generatedAt": "2026-05-27T00:44:06.845Z",
|
|
5
5
|
"commands": [
|
|
6
6
|
{
|
|
7
7
|
"name": "convert-mail-attachment-to-markdown",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"name": "convert-mail-to-markdown",
|
|
56
|
-
"summary": "Render a single Outlook email as markdown — headers (`**Subject:**`, `**From:**`, `**To:**`, `**Cc:**` only when present, `**Date:**`), followed by the body run through turndown.
|
|
56
|
+
"summary": "Render a single Outlook email as markdown — headers (`**Subject:**`, `**From:**`, `**To:**`, `**Cc:**` only when present, `**Date:**`), followed by the body run through turndown. By default, inline images (`isInline:true` + `image/*` content-type, size ≤ 2 MB) are embedded as base64 `data:` URIs so the output is self-contained (non-image inline attachments are NOT embedded; oversize inline images are replaced with a placeholder note). For LLM callers that only want the text body, pass `--inline-images false` to skip the per-image bytes fetch entirely — the body keeps raw `cid:<contentId>` references and the inline images surface in the file-attachments list so you can decide whether to fetch them separately via `get-mail-attachment`. File attachments are always listed below the body by name + size + id; their bytes are NOT fetched here — call `convert-mail-attachment-to-pdf` or `get-mail-attachment` with the id when you actually need them. Staged-fetch design (audit v1.0.0): one call for the body, one for the attachments-metadata list (only if `hasAttachments:true`), and one per small inline image — replaces the old `?$expand=attachments` which timed out / truncated on messages with multi-MB attachments.",
|
|
57
57
|
"category": "mail",
|
|
58
58
|
"graphMethod": "GET",
|
|
59
59
|
"graphPathTemplate": "/me/messages/{message-id}",
|
|
@@ -64,6 +64,12 @@
|
|
|
64
64
|
"key": "messageId",
|
|
65
65
|
"required": true,
|
|
66
66
|
"description": "Outlook message ID. Returned by `list-mail-messages` or `list-mail-folder-messages`."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "inline-images",
|
|
70
|
+
"key": "inlineImages",
|
|
71
|
+
"required": false,
|
|
72
|
+
"description": "Pass `--inline-images false` to skip the per-image bytes fetch + base64 embedding. Default is `true` (embed). Disabling cuts the response size dramatically on emails with several inline images (a 6 KB body with 6 inline images shipped at ~36 KB by default; with `--inline-images false` it stays close to 6 KB). The body keeps raw `cid:<contentId>` references and the inline images surface in the file-attachments list instead, so the LLM caller can still see what is there and fetch any specific image via `get-mail-attachment` on demand."
|
|
67
73
|
}
|
|
68
74
|
],
|
|
69
75
|
"example": "ask-marcel convert-mail-to-markdown --message-id 'AAMkAD...'",
|
|
@@ -118,68 +124,8 @@
|
|
|
118
124
|
"responseShape": "`{ contentType: \"application/pdf\", size, base64 }` — the PDF bytes, inlined. The CLI follows the SharePoint media-transform redirect internally so the LLM never has to fetch an external URL. Plain-text and pdf sources skip the format=pdf round-trip and return the raw file bytes under the same envelope shape (with their native contentType) plus `passthrough: true` and a `note` explaining why conversion was skipped — the LLM can branch on the flag if it cares whether Graph actually converted. Pair with the global `--output-path` to land the bytes on disk and replace `base64` with `savedTo` for multi-MB PDFs."
|
|
119
125
|
},
|
|
120
126
|
{
|
|
121
|
-
"name": "download-drive-item-version
|
|
122
|
-
"summary": "Download a *historical version
|
|
123
|
-
"category": "drive",
|
|
124
|
-
"graphMethod": "GET",
|
|
125
|
-
"graphPathTemplate": "/drives/{drive-id}/items/{item-id}/versions/{version-id}/content?format=html",
|
|
126
|
-
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/driveitemversion-get-content",
|
|
127
|
-
"options": [
|
|
128
|
-
{
|
|
129
|
-
"name": "drive-id",
|
|
130
|
-
"key": "driveId",
|
|
131
|
-
"required": true,
|
|
132
|
-
"description": "Microsoft Graph drive ID. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
"name": "item-id",
|
|
136
|
-
"key": "itemId",
|
|
137
|
-
"required": true,
|
|
138
|
-
"description": "driveItem ID of the file. Returned by `list-folder-files` or `search-onedrive-files`."
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
"name": "version-id",
|
|
142
|
-
"key": "versionId",
|
|
143
|
-
"required": true,
|
|
144
|
-
"description": "driveItemVersion ID. Returned by `ask-marcel list-drive-item-versions`. Pick a non-current version (the first entry is the live file and Graph rejects this endpoint for it)."
|
|
145
|
-
}
|
|
146
|
-
],
|
|
147
|
-
"example": "ask-marcel download-drive-item-version-as-markdown --drive-id 'b!1234' --item-id '01ABC' --version-id '4.0'",
|
|
148
|
-
"responseShape": "`{ contentType: \"text/markdown\", size: <chars>, text: \"...\" }` for the converted case; raw-bytes envelope for plain-text source extensions."
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
"name": "download-drive-item-version-as-pdf",
|
|
152
|
-
"summary": "Convert a *historical version* of a OneDrive / SharePoint file to PDF and return the bytes inline. Same shape as `download-drive-item-as-pdf` plus a `--version-id`. The CLI uses an ODSP-elevated token (M365ChatClient identity captured at login) for both the Graph call and the CDN-redirect follow, so the LLM never has to fetch an external URL. Plain-text source extensions and `pdf` sources short-circuit to a raw-bytes return. Note: Graph's `?format=pdf` sometimes serves the *current* version through this endpoint, but not reliably — audit v1.0.0 §D4 saw it fall back to raw source bytes (`passthrough: true`) even for the current version on the test tenant. For the current version always use `download-drive-item-as-pdf` so you don't depend on this quirk. When the response carries `passthrough: true`, the bytes are the source file (not a PDF); save them with the source extension, not `.pdf` — the global output-path flag refuses the mismatch (audit §B4).",
|
|
153
|
-
"category": "drive",
|
|
154
|
-
"graphMethod": "GET",
|
|
155
|
-
"graphPathTemplate": "/drives/{drive-id}/items/{item-id}/versions/{version-id}/content?format=pdf",
|
|
156
|
-
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/driveitemversion-get-content",
|
|
157
|
-
"options": [
|
|
158
|
-
{
|
|
159
|
-
"name": "drive-id",
|
|
160
|
-
"key": "driveId",
|
|
161
|
-
"required": true,
|
|
162
|
-
"description": "Microsoft Graph drive ID. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
"name": "item-id",
|
|
166
|
-
"key": "itemId",
|
|
167
|
-
"required": true,
|
|
168
|
-
"description": "driveItem ID of the file. Returned by `list-folder-files` or `search-onedrive-files`."
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
"name": "version-id",
|
|
172
|
-
"key": "versionId",
|
|
173
|
-
"required": true,
|
|
174
|
-
"description": "driveItemVersion ID. Returned by `ask-marcel list-drive-item-versions`. Pick a non-current version — the first entry (e.g. `12.0`) is the live file and Graph rejects this endpoint for it; use `value[1]` or older."
|
|
175
|
-
}
|
|
176
|
-
],
|
|
177
|
-
"example": "ask-marcel download-drive-item-version-as-pdf --drive-id 'b!1234' --item-id '01ABC' --version-id '4.0'",
|
|
178
|
-
"responseShape": "`{ contentType: \"application/pdf\", size, base64 }` — the historical-version PDF bytes, inlined. Plain-text and pdf sources skip the format=pdf round-trip and return the raw file bytes under the same envelope shape with `passthrough: true` + a `note` so the caller can tell conversion was deliberately skipped. **If Graph silently falls back to raw bytes** (some historical versions of pptx/docx — verified live), the response also carries `passthrough: true` + a sharp note saying the bytes are the source, NOT a PDF — save them with the source extension, not `.pdf`. Pair with the global `--output-path` to land the bytes on disk and replace `base64` with `savedTo`."
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
"name": "download-drive-item-version-content",
|
|
182
|
-
"summary": "Download the bytes of a *non-current* historical version of a OneDrive / SharePoint file, inlined. Graph refuses to serve the current version through this endpoint with \"You cannot get the content of the current version\" — for the current version use `download-onedrive-file-content`. The CLI follows the SharePoint streamContent redirect internally using an M365ChatClient-elevated token (captured at login) so the LLM never has to fetch an external URL.",
|
|
127
|
+
"name": "download-drive-item-version",
|
|
128
|
+
"summary": "Download a *non-current* historical version of a OneDrive / SharePoint file. `--format original` (default) returns the raw bytes — Graph refuses to serve the current version through this endpoint with \"You cannot get the content of the current version\"; for the current version use `download-onedrive-file-content`. `--format pdf` runs Graph `?format=pdf` for Office docs; plain-text and `pdf` sources short-circuit to raw bytes with `passthrough: true` + a note (Graph rejects `pdf → pdf` with InputFormatNotSupported). `--format markdown` runs the local conversion pipeline (mammoth for docx, sheetjs for xlsx, csv → table, plain-text passthrough). All three formats use an M365ChatClient-elevated Graph token (captured at login from m365.cloud.microsoft) — the Teams web client token returns 403 logicalPermissionAccessDenied on historical-version stream content. The CLI follows the SharePoint streamContent redirect internally so the LLM never has to fetch an external URL. Audit v1.0.0 §D4 caveat for `--format pdf`: Graph sometimes silently falls back to raw source bytes for the current version (which Graph occasionally serves through this endpoint) — when the response carries `passthrough: true`, save with the source extension, not `.pdf` (the global output-path flag refuses the mismatch).",
|
|
183
129
|
"category": "drive",
|
|
184
130
|
"graphMethod": "GET",
|
|
185
131
|
"graphPathTemplate": "/drives/{drive-id}/items/{item-id}/versions/{version-id}/content",
|
|
@@ -202,10 +148,24 @@
|
|
|
202
148
|
"key": "versionId",
|
|
203
149
|
"required": true,
|
|
204
150
|
"description": "driveItemVersion ID. Returned by `ask-marcel list-drive-item-versions`. Use the `id` field of an entry under `value[]`. Pick a non-current version — the first entry (e.g. `12.0`) is the live file and Graph rejects this endpoint for it; use `value[1]` or older."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"name": "format",
|
|
154
|
+
"key": "format",
|
|
155
|
+
"required": false,
|
|
156
|
+
"description": "Output format. `original` (default) returns the raw historical-version bytes. `pdf` runs Graph `?format=pdf` for Office sources (docx/pptx/xlsx) — plain-text and pdf sources short-circuit to raw bytes with `passthrough: true`. `markdown` runs the local conversion pipeline (mammoth/sheetjs/csv/plain-text). All formats inline the bytes; pair with the global `--output-path` to land them on disk.",
|
|
157
|
+
"argumentHint": {
|
|
158
|
+
"kind": "magicValue",
|
|
159
|
+
"values": [
|
|
160
|
+
"original",
|
|
161
|
+
"pdf",
|
|
162
|
+
"markdown"
|
|
163
|
+
]
|
|
164
|
+
}
|
|
205
165
|
}
|
|
206
166
|
],
|
|
207
|
-
"example": "ask-marcel download-drive-item-version
|
|
208
|
-
"responseShape": "`{ contentType, size, base64 }` — the
|
|
167
|
+
"example": "ask-marcel download-drive-item-version --drive-id 'b!1234' --item-id '01ABC' --version-id '4.0' --format pdf",
|
|
168
|
+
"responseShape": "`--format original` & `--format pdf`: `{ contentType, size, base64 }` — the bytes, inlined. `--format pdf` adds `passthrough: true` + `note` when Graph short-circuits (plain-text or pdf source) OR silently falls back to raw source bytes — in that case save with the source extension, NOT `.pdf` (the global output-path flag refuses the mismatch). `--format markdown`: `{ contentType: \"text/markdown\", size: <chars>, text: \"...\" }` for the converted case; raw-bytes envelope for plain-text source extensions. Pair with the global `--output-path` to land bytes on disk and replace `base64`/`text` with `savedTo` for multi-MB versions."
|
|
209
169
|
},
|
|
210
170
|
{
|
|
211
171
|
"name": "download-onedrive-file-content",
|
|
@@ -249,6 +209,37 @@
|
|
|
249
209
|
"example": "ask-marcel extract-sharepoint-links-in-mail --message-id 'AAMkADk0...'",
|
|
250
210
|
"responseShape": "`{ messageId, subject, links: [{ url, driveId, itemId, name, webUrl } | { url, error }], truncated, skippedCount }` — one entry per unique SharePoint URL found in the body, ordered by first occurrence."
|
|
251
211
|
},
|
|
212
|
+
{
|
|
213
|
+
"name": "find-chats-with-user",
|
|
214
|
+
"summary": "Find every Microsoft Teams chat that includes a member matching `--name` (substring search across display-name, email, given-name, surname, MRI, and object-id). Both sides are Unicode-folded (NFD + combining-mark strip) and lowercased before comparison, so `--name Herve` matches `Hervé ATTANE` AND `herve.attane@lvmh.com` AND `HERVÉ` — important because a dual-identity user often carries the accented display-name on one identity and the un-accented email on the other. Walks the paginated chat-list substrate up to `--max-pages` and returns matching chats with their `matchedMembers[]`. Collapses the canonical \"all conversations with person X\" workflow into a single call AND surfaces dual-identity people (e.g. someone with both an org MRI and a guest-tenant MRI). **Best-effort, may break on Microsoft client updates** — the chat substrate is not in the public Microsoft Graph API.",
|
|
215
|
+
"category": "chats",
|
|
216
|
+
"graphMethod": "GET",
|
|
217
|
+
"graphPathTemplate": "https://teams.microsoft.com/api/csa/{region}/api/v3/teams/users/me/chats",
|
|
218
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/chat-list",
|
|
219
|
+
"options": [
|
|
220
|
+
{
|
|
221
|
+
"name": "name",
|
|
222
|
+
"key": "name",
|
|
223
|
+
"required": true,
|
|
224
|
+
"description": "Substring to search across each chat member's `displayName`, `email`, `userPrincipalName`, `givenName`, `surname`, `mri`, `objectId`, and `jobTitle`. Both the query and each field are NFD-normalized + diacritics-stripped + lowercased before comparison, so `Hervé` ↔ `Herve` ↔ `HERVÉ` are equivalent and a query for the accented name still matches a member whose displayName is the un-accented email. Use the full name or an unambiguous fragment. Quoted multi-word values match on the joined substring, not per-token."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"name": "max-pages",
|
|
228
|
+
"key": "maxPages",
|
|
229
|
+
"required": false,
|
|
230
|
+
"description": "Safety cap on the chat-list walk (positive integer; default 10). Each page returns up to `--page-size` chats. Raise carefully on busy accounts — every page is one HTTP round-trip."
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"name": "page-size",
|
|
234
|
+
"key": "pageSize",
|
|
235
|
+
"required": false,
|
|
236
|
+
"description": "Chats per page (positive integer; default 100, same value Teams web uses). Server may silently cap."
|
|
237
|
+
}
|
|
238
|
+
],
|
|
239
|
+
"example": "ask-marcel find-chats-with-user --name 'Hervé ATTANE'",
|
|
240
|
+
"responseShape": "`{ name, matches: [{ chatId, title, chatType, threadType, memberCount, lastMessageAt?, matchedMembers: [{ mri, displayName, email, userSubType }] }], matchCount, pagesFetched, chatsScanned, hasMore, nextContinuationToken? }`. `matchedMembers` always carries the matching entries' identifying fields — pass `chatId` into `list-teams-chat-history` to read message bodies. `hasMore: true` means `--max-pages` was hit before exhausting the chat list; chain with the existing `--continuation-token` flag on `list-teams-chats-with-messages` if you need to scan further (this command does not advertise a `--continuation-token` because resuming a partial search is rare; users either widen `--max-pages` or refine `--name`).",
|
|
241
|
+
"stability": "experimental"
|
|
242
|
+
},
|
|
252
243
|
{
|
|
253
244
|
"name": "get-calendar-event",
|
|
254
245
|
"summary": "Fetch a single calendar event by ID from the signed-in user’s default calendar. Pass `--select` to project only the fields you need (the full event body can be large with HTML body and attendee lists).",
|
|
@@ -317,7 +308,7 @@
|
|
|
317
308
|
},
|
|
318
309
|
{
|
|
319
310
|
"name": "get-chat",
|
|
320
|
-
"summary": "Return metadata for a single Microsoft Teams chat (1:1, group, or meeting).
|
|
311
|
+
"summary": "Return metadata for a single Microsoft Teams chat (1:1, group, or meeting). The CLI ships a slim default `--select=id,topic,chatType,createdDateTime,lastUpdatedDateTime`; pass `--select id,topic,webUrl,onlineMeetingInfo` (or any other comma-separated field list) to widen. Pass `--expand members` to inline membership. Returns metadata only — not the messages (which need `Chat.Read*`). Requires the M365ChatClient elevated token captured at login (the basic Teams web client token lacks `Chat.ReadBasic`).",
|
|
321
312
|
"category": "chats",
|
|
322
313
|
"graphMethod": "GET",
|
|
323
314
|
"graphPathTemplate": "/chats/{chat-id}",
|
|
@@ -328,14 +319,26 @@
|
|
|
328
319
|
"key": "chatId",
|
|
329
320
|
"required": true,
|
|
330
321
|
"description": "Microsoft Teams chat ID, e.g. `19:abc...@thread.v2`. Returned by `list-chats`."
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"name": "select",
|
|
325
|
+
"key": "select",
|
|
326
|
+
"required": false,
|
|
327
|
+
"description": "OData $select: comma-separated list of fields to include in each item (e.g. `id,subject,from`). May shrink payloads dramatically — Graph honors $select on most endpoints, but some collections (notably `/me/mailboxSettings`, `/me/outlook/masterCategories`, `/me/mailFolders/inbox/messageRules`) silently ignore it and always return the full resource. Bogus field names are silently dropped by Graph — if a field you asked for is missing from the response, double-check the spelling against the documented `responseShape`."
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"name": "expand",
|
|
331
|
+
"key": "expand",
|
|
332
|
+
"required": false,
|
|
333
|
+
"description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
|
|
331
334
|
}
|
|
332
335
|
],
|
|
333
336
|
"example": "ask-marcel get-chat --chat-id '19:abc...@thread.v2'",
|
|
334
|
-
"responseShape": "single Microsoft Graph `chat` resource"
|
|
337
|
+
"responseShape": "single Microsoft Graph `chat` resource projected to the default `--select` set (or, when overridden, to the requested fields). `--expand members` adds an inline `members[]` array."
|
|
335
338
|
},
|
|
336
339
|
{
|
|
337
340
|
"name": "get-current-user",
|
|
338
|
-
"summary": "Return the signed-in user
|
|
341
|
+
"summary": "Return the signed-in user's Microsoft Graph profile. The CLI ships a slim default `--select=id,displayName,mail,userPrincipalName,jobTitle,officeLocation,mobilePhone` covering the common identity fields. Pass `--select id,displayName,givenName,surname,preferredLanguage,...` to widen, or `--select '*'` for everything Graph returns.",
|
|
339
342
|
"category": "user",
|
|
340
343
|
"graphMethod": "GET",
|
|
341
344
|
"graphPathTemplate": "/me",
|
|
@@ -354,8 +357,8 @@
|
|
|
354
357
|
"description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
|
|
355
358
|
}
|
|
356
359
|
],
|
|
357
|
-
"example": "ask-marcel get-current-user
|
|
358
|
-
"responseShape": "single Microsoft Graph `user` resource (or
|
|
360
|
+
"example": "ask-marcel get-current-user",
|
|
361
|
+
"responseShape": "single Microsoft Graph `user` resource projected to the default `--select` set (or, when overridden, to the requested fields)"
|
|
359
362
|
},
|
|
360
363
|
{
|
|
361
364
|
"name": "get-drive-delta",
|
|
@@ -763,7 +766,7 @@
|
|
|
763
766
|
},
|
|
764
767
|
{
|
|
765
768
|
"name": "get-excel-used-range",
|
|
766
|
-
"summary": "Return the worksheet's used range — the bounding box of every non-empty cell — as a single Excel range. Avoids fetching the entire 1M × 16K-cell sheet when only a small data island is populated.",
|
|
769
|
+
"summary": "Return the worksheet's used range — the bounding box of every non-empty cell — as a single Excel range. The CLI ships a slim default that strips the redundant `text` / `numberFormat` / `formulas` 2D arrays Graph returns (mostly `\"General\"` repeated cell-by-cell), keeping `address` / `rowCount` / `columnCount` / `values`. Pass `--full true` to return the raw four-array Graph shape. `--max-cells` (default 50 000) caps the size of the projected `values[]`; oversize ranges drop `values` and surface a hint pointing at `get-excel-range` for band-by-band reads. Avoids fetching the entire 1M × 16K-cell sheet when only a small data island is populated.",
|
|
767
770
|
"category": "excel",
|
|
768
771
|
"graphMethod": "GET",
|
|
769
772
|
"graphPathTemplate": "/drives/{drive-id}/items/{item-id}/workbook/worksheets/{worksheet-id}/usedRange()",
|
|
@@ -789,10 +792,22 @@
|
|
|
789
792
|
"argumentHint": {
|
|
790
793
|
"kind": "idOrName"
|
|
791
794
|
}
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
"name": "full",
|
|
798
|
+
"key": "full",
|
|
799
|
+
"required": false,
|
|
800
|
+
"description": "Pass `--full true` to return the raw Graph `workbookRange` shape with all four 2D arrays (`values`, `text`, `numberFormat`, `formulas`). Default (`--full false`, or omitted) drops the three redundant arrays and ships only `values`. The raw shape on a 3×148 sheet is ~125 KB (most of it duplicated `\"General\"` numberFormat strings); the slim default is ~5-15 KB."
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"name": "max-cells",
|
|
804
|
+
"key": "maxCells",
|
|
805
|
+
"required": false,
|
|
806
|
+
"description": "Cap (positive integer; default 50 000) on the size of the projected `values[]` in slim mode. When the used-range exceeds the cap, the response keeps `address` / `rowCount` / `columnCount` but drops `values[]` and adds `truncated: true` plus a hint pointing at `get-excel-range` for band-by-band reads. Ignored when `--full true` is set (the caller has opted into the full payload regardless of size)."
|
|
792
807
|
}
|
|
793
808
|
],
|
|
794
809
|
"example": "ask-marcel get-excel-used-range --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1'",
|
|
795
|
-
"responseShape": "
|
|
810
|
+
"responseShape": "Slim projection (default): `{ address, rowCount, columnCount, values, projection: 'slim' }` — `values[]` is the 2D cell-value array. Oversize variant: `{ address, rowCount, columnCount, projection: 'slim', truncated: true, maxCells, hint }` (no `values`). With `--full true`: the raw Graph `workbookRange` resource (adds `text`, `numberFormat`, `formulas` 2D arrays) plus `projection: 'full'`. Workbook Online (WAC) errors are translated to a clear `item is not an accessible Excel workbook` envelope (see `excel-error.ts`)."
|
|
796
811
|
},
|
|
797
812
|
{
|
|
798
813
|
"name": "get-group",
|
|
@@ -862,7 +877,7 @@
|
|
|
862
877
|
},
|
|
863
878
|
{
|
|
864
879
|
"name": "get-mail-message",
|
|
865
|
-
"summary": "Get a single Outlook message by ID
|
|
880
|
+
"summary": "Get a single Outlook message by ID. The CLI ships a slim default `--select=id,subject,from,toRecipients,ccRecipients,receivedDateTime,hasAttachments,isRead,importance,bodyPreview` so an LLM caller doesn't pull a 41 KB resource just to read a subject line. Pass `--select id,subject,body` (or any other comma-separated field list) to override; for the raw RFC-822 source use `get-mail-message-mime` instead.",
|
|
866
881
|
"category": "mail",
|
|
867
882
|
"graphMethod": "GET",
|
|
868
883
|
"graphPathTemplate": "/me/messages/{message-id}",
|
|
@@ -887,8 +902,8 @@
|
|
|
887
902
|
"description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
|
|
888
903
|
}
|
|
889
904
|
],
|
|
890
|
-
"example": "ask-marcel get-mail-message --message-id 'AAMkAGI2...'
|
|
891
|
-
"responseShape": "single Microsoft Graph `message` resource (or
|
|
905
|
+
"example": "ask-marcel get-mail-message --message-id 'AAMkAGI2...'",
|
|
906
|
+
"responseShape": "single Microsoft Graph `message` resource projected to the default `--select` set (or, when overridden, to the requested fields). The default omits `body`, `internetMessageHeaders`, and `uniqueBody` — request them explicitly via `--select` when you need the full HTML."
|
|
892
907
|
},
|
|
893
908
|
{
|
|
894
909
|
"name": "get-mail-message-mime",
|
|
@@ -1617,6 +1632,31 @@
|
|
|
1617
1632
|
"example": "ask-marcel get-team-primary-channel --team-id 'tm1'",
|
|
1618
1633
|
"responseShape": "single Microsoft Graph `channel` resource"
|
|
1619
1634
|
},
|
|
1635
|
+
{
|
|
1636
|
+
"name": "get-teams-chat-message",
|
|
1637
|
+
"summary": "Return a single Microsoft Teams chat message by its id via the chat substrate. Uses the chatsvcagg-audience bearer captured at login (same identity as the basic Teams token, different audience). **Best-effort, may break on Microsoft client updates** — the chat substrate is not in the public Microsoft Graph API. Source the chat-id + message-id via `list-teams-chats-with-messages` or `list-teams-chat-messages`.",
|
|
1638
|
+
"category": "chats",
|
|
1639
|
+
"graphMethod": "GET",
|
|
1640
|
+
"graphPathTemplate": "https://teams.microsoft.com/api/csa/{region}/api/v1/chats/{chat-id}/messages/{message-id}",
|
|
1641
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/chatmessage-get",
|
|
1642
|
+
"options": [
|
|
1643
|
+
{
|
|
1644
|
+
"name": "chat-id",
|
|
1645
|
+
"key": "chatId",
|
|
1646
|
+
"required": true,
|
|
1647
|
+
"description": "Teams chat ID. Source via `list-chats` or `list-teams-chats-with-messages`."
|
|
1648
|
+
},
|
|
1649
|
+
{
|
|
1650
|
+
"name": "message-id",
|
|
1651
|
+
"key": "messageId",
|
|
1652
|
+
"required": true,
|
|
1653
|
+
"description": "Teams chat message ID. Source via `list-teams-chats-with-messages` or `list-teams-chat-messages`."
|
|
1654
|
+
}
|
|
1655
|
+
],
|
|
1656
|
+
"example": "ask-marcel get-teams-chat-message --chat-id '19:abc...@unq.gbl.spaces' --message-id '1700000000000'",
|
|
1657
|
+
"responseShape": "single Teams chat message — `id`, `from`, `imDisplayName`, `content`, `contentType`, `composeTime`, `originalArrivalTime`, etc. **Microsoft-internal schema — fields may change without notice.**",
|
|
1658
|
+
"stability": "experimental"
|
|
1659
|
+
},
|
|
1620
1660
|
{
|
|
1621
1661
|
"name": "get-todo-task",
|
|
1622
1662
|
"summary": "Get a single Microsoft To Do task by its ID and its parent list ID. Use `--select` to slim the response (e.g. `--select id,title,status`) or `--expand checklistItems` / `--expand linkedResources` to inline child collections.",
|
|
@@ -1779,13 +1819,13 @@
|
|
|
1779
1819
|
"name": "start-date-time",
|
|
1780
1820
|
"key": "startDateTime",
|
|
1781
1821
|
"required": true,
|
|
1782
|
-
"description": "ISO 8601
|
|
1822
|
+
"description": "Lower bound. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
1783
1823
|
},
|
|
1784
1824
|
{
|
|
1785
1825
|
"name": "end-date-time",
|
|
1786
1826
|
"key": "endDateTime",
|
|
1787
1827
|
"required": true,
|
|
1788
|
-
"description": "ISO 8601
|
|
1828
|
+
"description": "Upper bound. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
1789
1829
|
},
|
|
1790
1830
|
{
|
|
1791
1831
|
"name": "top",
|
|
@@ -2002,7 +2042,7 @@
|
|
|
2002
2042
|
},
|
|
2003
2043
|
{
|
|
2004
2044
|
"name": "list-calendar-view",
|
|
2005
|
-
"summary": "List the signed-in user
|
|
2045
|
+
"summary": "List the signed-in user's default-calendar events with recurrence expanded into individual occurrences in a date range. Both date-time params accept strict ISO 8601 (`2026-04-01T00:00:00Z`) AND the CLI's relative shapes (`7d`, `today`, `monday`, `start-of-month`, …) so a question like \"what's on my calendar this week\" no longer requires the LLM to compute timestamps by hand.",
|
|
2006
2046
|
"category": "calendar",
|
|
2007
2047
|
"graphMethod": "GET",
|
|
2008
2048
|
"graphPathTemplate": "/me/calendarView?startDateTime={start-date-time}&endDateTime={end-date-time}",
|
|
@@ -2012,13 +2052,13 @@
|
|
|
2012
2052
|
"name": "start-date-time",
|
|
2013
2053
|
"key": "startDateTime",
|
|
2014
2054
|
"required": true,
|
|
2015
|
-
"description": "ISO 8601
|
|
2055
|
+
"description": "Lower bound. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
2016
2056
|
},
|
|
2017
2057
|
{
|
|
2018
2058
|
"name": "end-date-time",
|
|
2019
2059
|
"key": "endDateTime",
|
|
2020
2060
|
"required": true,
|
|
2021
|
-
"description": "ISO 8601
|
|
2061
|
+
"description": "Upper bound. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
2022
2062
|
},
|
|
2023
2063
|
{
|
|
2024
2064
|
"name": "top",
|
|
@@ -2057,7 +2097,7 @@
|
|
|
2057
2097
|
"description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
|
|
2058
2098
|
}
|
|
2059
2099
|
],
|
|
2060
|
-
"example": "ask-marcel list-calendar-view --start-date-time '
|
|
2100
|
+
"example": "ask-marcel list-calendar-view --start-date-time 'start-of-week' --end-date-time 'end-of-week'",
|
|
2061
2101
|
"responseShape": "collection of Microsoft Graph `event` resources (single occurrences) under `value[]`"
|
|
2062
2102
|
},
|
|
2063
2103
|
{
|
|
@@ -2072,13 +2112,13 @@
|
|
|
2072
2112
|
"name": "start-date-time",
|
|
2073
2113
|
"key": "startDateTime",
|
|
2074
2114
|
"required": true,
|
|
2075
|
-
"description": "
|
|
2115
|
+
"description": "Lower bound (required on the first call only — the deltaLink token encodes it for resumes). ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
2076
2116
|
},
|
|
2077
2117
|
{
|
|
2078
2118
|
"name": "end-date-time",
|
|
2079
2119
|
"key": "endDateTime",
|
|
2080
2120
|
"required": true,
|
|
2081
|
-
"description": "
|
|
2121
|
+
"description": "Upper bound (required on the first call only — the deltaLink token encodes it for resumes). ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
2082
2122
|
},
|
|
2083
2123
|
{
|
|
2084
2124
|
"name": "top",
|
|
@@ -2179,7 +2219,7 @@
|
|
|
2179
2219
|
},
|
|
2180
2220
|
{
|
|
2181
2221
|
"name": "list-chats",
|
|
2182
|
-
"summary": "List the signed-in user's Microsoft Teams chats (1:1, group, and meeting chats).
|
|
2222
|
+
"summary": "List the signed-in user's Microsoft Teams chats (1:1, group, and meeting chats). The CLI ships a slim default `--select=id,topic,chatType,createdDateTime,lastUpdatedDateTime`; pass `--select id,topic,webUrl,...` to widen. Returns chat metadata only — reading chat *messages* needs `Chat.Read*` which neither token grants. Requires the M365ChatClient elevated token captured at login (the basic Teams web client token lacks `Chat.ReadBasic`). Graph rejects `$orderby` and hangs on `$expand` for this endpoint, so the CLI advertises only the subset Graph honours (`--top`, `--skip`, `--select`, `--filter`).",
|
|
2183
2223
|
"category": "chats",
|
|
2184
2224
|
"graphMethod": "GET",
|
|
2185
2225
|
"graphPathTemplate": "/me/chats",
|
|
@@ -2211,7 +2251,7 @@
|
|
|
2211
2251
|
}
|
|
2212
2252
|
],
|
|
2213
2253
|
"example": "ask-marcel list-chats",
|
|
2214
|
-
"responseShape": "collection of Microsoft Graph `chat` resources under `value[]`",
|
|
2254
|
+
"responseShape": "collection of Microsoft Graph `chat` resources under `value[]`, each projected to the default `--select` set (or, when overridden, to the requested fields).",
|
|
2215
2255
|
"pagination": true
|
|
2216
2256
|
},
|
|
2217
2257
|
{
|
|
@@ -2369,7 +2409,7 @@
|
|
|
2369
2409
|
},
|
|
2370
2410
|
{
|
|
2371
2411
|
"name": "list-drive-item-versions",
|
|
2372
|
-
"summary": "List the historical versions of a OneDrive / SharePoint file (each save creates a new version). Note: each version's `id` is a stringified float like `\"79.0\"` (NOT an integer like `79`) — pass it literally to
|
|
2412
|
+
"summary": "List the historical versions of a OneDrive / SharePoint file (each save creates a new version). Note: each version's `id` is a stringified float like `\"79.0\"` (NOT an integer like `79`) — pass it literally to the `download-drive-item-version` command (it accepts an `original | pdf | markdown` format selector); numeric coercion silently fails because Graph rejects `79` against a path templated for stringified floats.",
|
|
2373
2413
|
"category": "drive",
|
|
2374
2414
|
"graphMethod": "GET",
|
|
2375
2415
|
"graphPathTemplate": "/drives/{drive-id}/items/{item-id}/versions",
|
|
@@ -3051,13 +3091,13 @@
|
|
|
3051
3091
|
"name": "start-date-time",
|
|
3052
3092
|
"key": "startDateTime",
|
|
3053
3093
|
"required": true,
|
|
3054
|
-
"description": "ISO 8601
|
|
3094
|
+
"description": "Start of the window (recurrences are expanded across it). ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
3055
3095
|
},
|
|
3056
3096
|
{
|
|
3057
3097
|
"name": "end-date-time",
|
|
3058
3098
|
"key": "endDateTime",
|
|
3059
3099
|
"required": true,
|
|
3060
|
-
"description": "ISO 8601
|
|
3100
|
+
"description": "End of the window. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
3061
3101
|
},
|
|
3062
3102
|
{
|
|
3063
3103
|
"name": "top",
|
|
@@ -3827,7 +3867,7 @@
|
|
|
3827
3867
|
},
|
|
3828
3868
|
{
|
|
3829
3869
|
"name": "list-mail-messages",
|
|
3830
|
-
"summary": "List the most recent messages from across the signed-in user
|
|
3870
|
+
"summary": "List the most recent messages from across the signed-in user's entire Outlook mailbox (every folder including Sent, Archive, Junk; default sort `receivedDateTime` desc). The CLI ships a slim default `--select=id,subject,from,toRecipients,ccRecipients,receivedDateTime,hasAttachments,isRead,importance,bodyPreview` so a page of 25 messages stays ~30-60 KB instead of ~1 MB. Pass `--select id,subject,body` (or any other comma-separated field list) to override. Use `list-mail-folder-messages` to scope to a single folder such as Inbox.",
|
|
3831
3871
|
"category": "mail",
|
|
3832
3872
|
"graphMethod": "GET",
|
|
3833
3873
|
"graphPathTemplate": "/me/messages",
|
|
@@ -3871,7 +3911,7 @@
|
|
|
3871
3911
|
}
|
|
3872
3912
|
],
|
|
3873
3913
|
"example": "ask-marcel list-mail-messages",
|
|
3874
|
-
"responseShape": "collection of Microsoft Graph `message` resources under `value[]`",
|
|
3914
|
+
"responseShape": "collection of Microsoft Graph `message` resources under `value[]`, each projected to the default `--select` set (or the requested fields when overridden). The default omits `body`, `internetMessageHeaders`, and `uniqueBody`.",
|
|
3875
3915
|
"pagination": true
|
|
3876
3916
|
},
|
|
3877
3917
|
{
|
|
@@ -4700,13 +4740,13 @@
|
|
|
4700
4740
|
"name": "start-date-time",
|
|
4701
4741
|
"key": "startDateTime",
|
|
4702
4742
|
"required": true,
|
|
4703
|
-
"description": "ISO 8601 start of the
|
|
4743
|
+
"description": "Start of the window. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
4704
4744
|
},
|
|
4705
4745
|
{
|
|
4706
4746
|
"name": "end-date-time",
|
|
4707
4747
|
"key": "endDateTime",
|
|
4708
4748
|
"required": true,
|
|
4709
|
-
"description": "ISO 8601
|
|
4749
|
+
"description": "End of the window. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
4710
4750
|
},
|
|
4711
4751
|
{
|
|
4712
4752
|
"name": "top",
|
|
@@ -5568,13 +5608,13 @@
|
|
|
5568
5608
|
"name": "start-date-time",
|
|
5569
5609
|
"key": "startDateTime",
|
|
5570
5610
|
"required": true,
|
|
5571
|
-
"description": "ISO 8601
|
|
5611
|
+
"description": "Lower bound. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
5572
5612
|
},
|
|
5573
5613
|
{
|
|
5574
5614
|
"name": "end-date-time",
|
|
5575
5615
|
"key": "endDateTime",
|
|
5576
5616
|
"required": true,
|
|
5577
|
-
"description": "ISO 8601
|
|
5617
|
+
"description": "Upper bound. ISO 8601 UTC (e.g. `2026-04-01T00:00:00Z` or `2026-04-01`) OR a relative shape: `7d` / `1w` / `2h` / `30m` (past), `+7d` (future), `today` / `yesterday` / `tomorrow` / `now`, `monday`-`sunday` (most recent), `last-<weekday>` / `next-<weekday>`, `start-of-week|month|year`, `end-of-week|month|year`. Relative forms resolve at request time relative to the CLI process clock (UTC)."
|
|
5578
5618
|
},
|
|
5579
5619
|
{
|
|
5580
5620
|
"name": "top",
|
|
@@ -5648,7 +5688,7 @@
|
|
|
5648
5688
|
},
|
|
5649
5689
|
{
|
|
5650
5690
|
"name": "list-team-installed-apps",
|
|
5651
|
-
"summary": "List the Teams apps installed in a team. The CLI hard-pins `$expand=teamsAppDefinition` so every entry includes `displayName`, `version`, and `distributionMethod` (the bare endpoint returns only opaque IDs). Useful for surfacing which integrations are wired into a given team. Graph rejects
|
|
5691
|
+
"summary": "List the Teams apps installed in a team. The CLI hard-pins `$expand=teamsAppDefinition` so every entry includes `displayName`, `version`, and `distributionMethod` (the bare endpoint returns only opaque IDs). Useful for surfacing which integrations are wired into a given team. Graph rejects user-supplied OData query parameters on this endpoint (`Query option 'Top' is not allowed`) — so the standard OData flags are intentionally NOT exposed here. The response itself is still server-paginated via `@odata.nextLink` when the team has many installed apps; chain with `next-page` to walk subsequent pages.",
|
|
5652
5692
|
"category": "teams",
|
|
5653
5693
|
"graphMethod": "GET",
|
|
5654
5694
|
"graphPathTemplate": "/teams/{team-id}/installedApps?$expand=teamsAppDefinition",
|
|
@@ -5665,6 +5705,99 @@
|
|
|
5665
5705
|
"responseShape": "collection of Microsoft Graph `teamsAppInstallation` resources under `value[]`, each with an inline `teamsAppDefinition` (`displayName`, `version`, `distributionMethod`)",
|
|
5666
5706
|
"pagination": true
|
|
5667
5707
|
},
|
|
5708
|
+
{
|
|
5709
|
+
"name": "list-teams-chat-history",
|
|
5710
|
+
"summary": "Deep read of a Microsoft Teams chat's message history via the IC3 substrate (`teams.microsoft.com/api/chatsvc/<region>/v1/...`). Unlike `list-teams-chat-messages` (which caps at the 200 most recent messages with no working pagination cursor), this command follows the server-provided `_metadata.syncState` URL backward through history, fetching up to `--page-size` * `--max-pages` messages per invocation (default 200 * 20 = 4000). Uses the IC3-audience bearer captured at login (same Teams web client identity as the basic Teams token). The CLI ships a slim default projection — each message is reduced to `id, sequenceId, composetime, originalarrivaltime, messagetype, from, imdisplayname, content` and `content` is truncated to 4096 chars (with `truncated: true` and `originalContentChars` set on the affected entries). Pass `--full true` to opt out of projection and truncation; pass `--max-content-chars N` to override the truncation cap. **Best-effort, may break on Microsoft client updates** — the IC3 substrate is not in the public Microsoft Graph API. To page beyond `--max-pages`, take the response's `nextSyncState` and pass it back as `--sync-state` on the next call.",
|
|
5711
|
+
"category": "chats",
|
|
5712
|
+
"graphMethod": "GET",
|
|
5713
|
+
"graphPathTemplate": "https://teams.microsoft.com/api/chatsvc/{region}/v1/users/ME/conversations/{chat-id}/messages",
|
|
5714
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/chatmessage-list",
|
|
5715
|
+
"options": [
|
|
5716
|
+
{
|
|
5717
|
+
"name": "chat-id",
|
|
5718
|
+
"key": "chatId",
|
|
5719
|
+
"required": true,
|
|
5720
|
+
"description": "Teams chat ID — typically `19:<thread>@unq.gbl.spaces` (1:1) or `19:<thread>@thread.v2` (group). Source via `list-chats` or `list-teams-chats-with-messages`."
|
|
5721
|
+
},
|
|
5722
|
+
{
|
|
5723
|
+
"name": "sync-state",
|
|
5724
|
+
"key": "syncState",
|
|
5725
|
+
"required": false,
|
|
5726
|
+
"description": "Opaque pagination URL returned in the prior response's `nextSyncState` field. Pass it back to continue paging backward from where the previous invocation stopped. Omit on the first call."
|
|
5727
|
+
},
|
|
5728
|
+
{
|
|
5729
|
+
"name": "page-size",
|
|
5730
|
+
"key": "pageSize",
|
|
5731
|
+
"required": false,
|
|
5732
|
+
"description": "Messages per IC3 page (positive integer; default 200). Server may silently cap."
|
|
5733
|
+
},
|
|
5734
|
+
{
|
|
5735
|
+
"name": "max-pages",
|
|
5736
|
+
"key": "maxPages",
|
|
5737
|
+
"required": false,
|
|
5738
|
+
"description": "Safety cap on the backward walk (positive integer; default 20). Each page can return up to `--page-size` messages, so default ceiling is ~4000 messages or ~4 MB inline JSON per invocation. Raise carefully — response is buffered fully before returning."
|
|
5739
|
+
},
|
|
5740
|
+
{
|
|
5741
|
+
"name": "full",
|
|
5742
|
+
"key": "full",
|
|
5743
|
+
"required": false,
|
|
5744
|
+
"description": "Pass `--full true` to return the raw IC3 substrate shape (every field on every message, no truncation). Default (`--full false`, or omitted) projects each message down to `id, sequenceId, composetime, originalarrivaltime, messagetype, from, imdisplayname, content` — covering 'who said what, when' without the IC3 envelope noise."
|
|
5745
|
+
},
|
|
5746
|
+
{
|
|
5747
|
+
"name": "max-content-chars",
|
|
5748
|
+
"key": "maxContentChars",
|
|
5749
|
+
"required": false,
|
|
5750
|
+
"description": "When the slim projection is active (i.e. `--full` is not `true`), cap each message `content` at this many characters; messages cut at the cap also carry `truncated: true` and `originalContentChars` so a consumer can decide whether to re-fetch with `--full true`. Default 4096. Ignored when `--full true` is set."
|
|
5751
|
+
}
|
|
5752
|
+
],
|
|
5753
|
+
"example": "ask-marcel list-teams-chat-history --chat-id '19:abc...@unq.gbl.spaces' --max-pages 5",
|
|
5754
|
+
"responseShape": "`{ messages: [...], hasMore: boolean, pagesFetched: number, nextSyncState?: string, projection: 'slim' | 'full' }`. Slim projection (default) emits `{ id, sequenceId, composetime, originalarrivaltime, messagetype, from, imdisplayname, content }` per message, with `truncated: true` + `originalContentChars` on entries whose `content` exceeded `--max-content-chars` (default 4096). With `--full true`, returns the raw IC3 substrate shape: `id`, `sequenceId` (monotonic per-chat counter), `composetime`, `originalarrivaltime`, `messagetype`, `content`, `from`, `imdisplayname`, `properties.subject`, etc. **`hasMore: true`** means the safety cap was hit and there is older history beyond what was returned — chain a follow-up call with `--sync-state $(jq -r .data.nextSyncState <prev>)` to continue. **`hasMore: false`** means the chat's earliest message was reached. **Microsoft-internal schema — fields may change without notice.**",
|
|
5755
|
+
"stability": "experimental"
|
|
5756
|
+
},
|
|
5757
|
+
{
|
|
5758
|
+
"name": "list-teams-chat-messages",
|
|
5759
|
+
"summary": "List the most recent messages in a single Microsoft Teams chat via the chat substrate. Companion to `list-teams-chats-with-messages` when the inlined `lastMessage` isn't deep enough. Uses the chatsvcagg-audience bearer captured at login. **Best-effort, may break on Microsoft client updates** — the chat substrate is not in the public Microsoft Graph API. **No pagination**: the route caps at the 200 most recent messages per chat and the CLI cannot reach older history (Teams web itself uses WebSockets for scrollback, and the official `Chat.Read` Graph scope that would enable paginated reads is outside the appid's scope ceiling).",
|
|
5760
|
+
"category": "chats",
|
|
5761
|
+
"graphMethod": "GET",
|
|
5762
|
+
"graphPathTemplate": "https://teams.microsoft.com/api/csa/{region}/api/v1/chats/{chat-id}/messages",
|
|
5763
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/chatmessage-list",
|
|
5764
|
+
"options": [
|
|
5765
|
+
{
|
|
5766
|
+
"name": "chat-id",
|
|
5767
|
+
"key": "chatId",
|
|
5768
|
+
"required": true,
|
|
5769
|
+
"description": "Teams chat ID — typically `19:<thread>@unq.gbl.spaces` (1:1) or `19:<thread>@thread.v2` (group). Source via `list-chats` or `list-teams-chats-with-messages`."
|
|
5770
|
+
}
|
|
5771
|
+
],
|
|
5772
|
+
"example": "ask-marcel list-teams-chat-messages --chat-id '19:abc...@unq.gbl.spaces'",
|
|
5773
|
+
"responseShape": "Substrate envelope: `{ messages: [...], messageToken: string }`. Returns up to the 200 most recent messages per chat — older history is NOT reachable via this endpoint. Each message has `id`, `from`, `imDisplayName`, `content`, `contentType`, `composeTime`, `originalArrivalTime`, `sequenceId`, etc. `messageToken` is returned for forward compatibility but is currently a static snapshot identifier (server ignores it as a pagination cursor). **Microsoft-internal schema — fields may change without notice.** For history older than the 200 most recent, use `list-teams-chat-history` (rides the IC3 substrate with a working syncState cursor).",
|
|
5774
|
+
"stability": "experimental"
|
|
5775
|
+
},
|
|
5776
|
+
{
|
|
5777
|
+
"name": "list-teams-chats-with-messages",
|
|
5778
|
+
"summary": "List the signed-in user's Microsoft Teams chats with the last message body inlined per chat. Uses the chatsvcagg-audience bearer captured at login. Paginated via `continuationToken` (default page size 100; pass the response's `continuationToken` back as `--continuation-token` while `hasMoreData: true`). **Best-effort, may break on Microsoft client updates**: the chat substrate is not part of the public Microsoft Graph API; Microsoft can change route shapes without notice. Caller Graph scopes do NOT matter here; the substrate server gates access on the appid + identity, not on Graph scopes.",
|
|
5779
|
+
"category": "chats",
|
|
5780
|
+
"graphMethod": "GET",
|
|
5781
|
+
"graphPathTemplate": "https://teams.microsoft.com/api/csa/{region}/api/v3/teams/users/me/chats",
|
|
5782
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/chat-list",
|
|
5783
|
+
"options": [
|
|
5784
|
+
{
|
|
5785
|
+
"name": "page-size",
|
|
5786
|
+
"key": "pageSize",
|
|
5787
|
+
"required": false,
|
|
5788
|
+
"description": "Chats per page (positive integer; default 100, same value Teams web uses). Server may silently cap."
|
|
5789
|
+
},
|
|
5790
|
+
{
|
|
5791
|
+
"name": "continuation-token",
|
|
5792
|
+
"key": "continuationToken",
|
|
5793
|
+
"required": false,
|
|
5794
|
+
"description": "Opaque pagination cursor returned in the prior response's `continuationToken` field. Omit on the first call; loop until `hasMoreData` is false."
|
|
5795
|
+
}
|
|
5796
|
+
],
|
|
5797
|
+
"example": "ask-marcel list-teams-chats-with-messages --page-size 100",
|
|
5798
|
+
"responseShape": "`{ chats: [...], continuationToken?: string, hasMoreData?: boolean }`. Each chat carries `id`, `title`, `chatType`, `threadType`, `members[]` (with each member's `mri`, `displayName`, `email`), `createdAt`, AND `lastMessage` (the most recent message body inlined — `content`, `from`, `composeTime`, `imDisplayName`, etc.). When `hasMoreData: true`, chain a follow-up call with `--continuation-token \"$(jq -r .data.continuationToken <prev>)\"`. **Microsoft-internal schema — fields may change without notice; treat the response as semi-structured.**",
|
|
5799
|
+
"stability": "experimental"
|
|
5800
|
+
},
|
|
5668
5801
|
{
|
|
5669
5802
|
"name": "list-todo-linked-resources",
|
|
5670
5803
|
"summary": "List the linked resources (URLs, emails, files) attached to a Microsoft To Do task.",
|
|
@@ -5998,14 +6131,14 @@
|
|
|
5998
6131
|
},
|
|
5999
6132
|
{
|
|
6000
6133
|
"name": "my-quick-context",
|
|
6001
|
-
"summary": "One-shot discovery for the IDs every other command needs. Issues
|
|
6134
|
+
"summary": "One-shot discovery for the IDs every other command needs, plus the user's job title and tenant timezone / locale / working-hours. Issues 9 Graph calls in parallel and returns what each succeeded for. Partial-result mode: only `/me` is load-bearing — if any other sub-call fails (missing license, scope, or tenant policy) the corresponding field is `undefined` but the rest are still returned. Replaces the audit's 5-call discovery chain — feed the IDs straight into `list-mail-folder-messages`, `list-folder-files`, `list-planner-tasks`, `list-onenote-notebook-sections`, etc. For Microsoft To Do lists call `list-todo-task-lists` on demand (intentionally dropped from this command's fan-out — the array of {id, displayName, wellknownListName} entries crowded the envelope with IDs an LLM rarely needs on first contact). Audit Hervé-session §5.2: `tenantTimeZone` lets an LLM stop treating every datetime as UTC on first contact.",
|
|
6002
6135
|
"category": "meta",
|
|
6003
6136
|
"graphMethod": "GET",
|
|
6004
|
-
"graphPathTemplate": "(meta) parallel: /me, /me/drive, /me/mailFolders/inbox, /me/
|
|
6137
|
+
"graphPathTemplate": "(meta) parallel: /me, /me/drive, /me/mailFolders/inbox, /me/calendar, /me/planner/plans, /me/onenote/notebooks, /me/joinedTeams, /me/drive/recent, /me/mailboxSettings",
|
|
6005
6138
|
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/user-get",
|
|
6006
6139
|
"options": [],
|
|
6007
6140
|
"example": "ask-marcel my-quick-context",
|
|
6008
|
-
"responseShape": "{ user: { id, displayName, userPrincipalName, mail }, primaryDriveId?, inboxId?,
|
|
6141
|
+
"responseShape": "`{ user: { id, displayName, userPrincipalName, mail, jobTitle? }, primaryDriveId?, inboxId?, primaryCalendarId?, primaryPlannerPlanId?, defaultNotebookId?, firstJoinedTeamId?, recentDriveItemId?, tenantTimeZone?, tenantLocale?, tenantWorkingHours?: { start, end, timeZone? } }` — every field except `user.id` is optional and absent when its source call failed. `user.jobTitle` is the user's role string from Azure AD (e.g. \"Engineering Manager\"). `tenantTimeZone` is the Outlook timezone string (e.g. \"Romance Standard Time\", \"Pacific Standard Time\"); `tenantLocale` is the IETF tag (e.g. \"en-US\"). For Microsoft To Do lists, call `list-todo-task-lists` separately — they were dropped from this command's fan-out to keep the envelope LLM-tractable."
|
|
6009
6142
|
},
|
|
6010
6143
|
{
|
|
6011
6144
|
"name": "next-page",
|
|
@@ -6028,20 +6161,92 @@
|
|
|
6028
6161
|
"example": "ask-marcel next-page --url 'https://graph.microsoft.com/v1.0/me/messages?$skip=10'",
|
|
6029
6162
|
"responseShape": "same shape as the originating endpoint — `{ ok: true, data: { value: [...] }, nextLink: \"...\" }` with the cursor at envelope level."
|
|
6030
6163
|
},
|
|
6164
|
+
{
|
|
6165
|
+
"name": "resolve-calendar-link",
|
|
6166
|
+
"summary": "Parse a Microsoft Outlook calendar item link (the URL emitted by the \"Copy link\" / share action on a calendar event) into its `eventId`. Pure transformation — no Graph call. Pipe the result into `get-calendar-event` to fetch the event body. For Outlook mail message links use `resolve-mail-link` instead — this command rejects them with a pointer.",
|
|
6167
|
+
"category": "calendar",
|
|
6168
|
+
"graphMethod": "GET",
|
|
6169
|
+
"graphPathTemplate": "{url}",
|
|
6170
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/event-get",
|
|
6171
|
+
"options": [
|
|
6172
|
+
{
|
|
6173
|
+
"name": "url",
|
|
6174
|
+
"key": "url",
|
|
6175
|
+
"required": true,
|
|
6176
|
+
"description": "Outlook web URL for a single calendar item. Accepted hosts: `outlook.office.com`, `outlook.office365.com`, `outlook.live.com`. Accepted shapes: path-style (`/calendar/item/AAMkA...`) and OWA query-style with calendar path (`/owa/?itemid=AAMkA...&path=/calendar/item`). Mail links (`/mail/...` or `/owa/?itemid=...` without `path=/calendar`) are rejected with `cli_reject_mail_link_on_calendar_resolver` — use `resolve-mail-link` for those."
|
|
6177
|
+
}
|
|
6178
|
+
],
|
|
6179
|
+
"example": "ask-marcel resolve-calendar-link --url 'https://outlook.office.com/calendar/item/AAMkAGI2THVS...'",
|
|
6180
|
+
"responseShape": "`{ eventId: string }`. `eventId` is URL-decoded and ready to pass to `get-calendar-event --event-id <id>`."
|
|
6181
|
+
},
|
|
6182
|
+
{
|
|
6183
|
+
"name": "resolve-drive-share-link",
|
|
6184
|
+
"summary": "Encode a OneDrive / SharePoint sharing URL into the Graph `/shares/{token}` share token (`u!<base64url>` per [shares-get](https://learn.microsoft.com/en-us/graph/api/shares-get)). Pure transformation — no Graph call. Pipe the returned `graphPath` (`/shares/{token}/driveItem`) into a sibling lookup (`get-drive-item`, `download-onedrive-file-content`, `convert-mail-attachment-to-pdf`, etc.) once the file has been resolved to a `driveItem`. Accepts any `*.sharepoint.com` URL (tenant + `*-my.sharepoint.com` personal OneDrive) and Microsoft's short-link host `1drv.ms`.",
|
|
6185
|
+
"category": "drive",
|
|
6186
|
+
"graphMethod": "GET",
|
|
6187
|
+
"graphPathTemplate": "{url}",
|
|
6188
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/shares-get",
|
|
6189
|
+
"options": [
|
|
6190
|
+
{
|
|
6191
|
+
"name": "url",
|
|
6192
|
+
"key": "url",
|
|
6193
|
+
"required": true,
|
|
6194
|
+
"description": "A OneDrive / SharePoint sharing URL — the address from the \"Copy link\" / \"Share\" action in the OneDrive or SharePoint UI. Examples: `https://contoso.sharepoint.com/:b:/s/sitename/EaB1cD...`, `https://contoso-my.sharepoint.com/personal/user_contoso_com/Documents/file.pdf`, `https://1drv.ms/b/s!AbCdEfGh...`. The CLI does not follow the redirect on `1drv.ms` links — the short URL itself is encoded as the share token (Graph resolves it on the server side)."
|
|
6195
|
+
}
|
|
6196
|
+
],
|
|
6197
|
+
"example": "ask-marcel resolve-drive-share-link --url 'https://contoso.sharepoint.com/:b:/s/team/EaB1cD2eF...?e=abc'",
|
|
6198
|
+
"responseShape": "`{ shareToken: string, graphPath: string, originalUrl: string }`. `shareToken` is the `u!<base64url>` form. `graphPath` is the ready-to-use `/shares/{token}/driveItem` URL — pass it to `ask-marcel next-page --url <link>` for a one-shot driveItem fetch, or feed the `shareToken` into any future `/shares/{token}/...` endpoint. `originalUrl` is echoed back for round-trip confirmation."
|
|
6199
|
+
},
|
|
6200
|
+
{
|
|
6201
|
+
"name": "resolve-mail-link",
|
|
6202
|
+
"summary": "Parse a Microsoft Outlook web mail link (the URL emitted by the \"Copy link\" / address-bar share of an email) into its `messageId`. Pure transformation — no Graph call. Pipe the result into `get-mail-message` to fetch the body, or `convert-mail-to-markdown` to render it. For Outlook calendar links use `resolve-calendar-link` instead — this command rejects them with a pointer.",
|
|
6203
|
+
"category": "mail",
|
|
6204
|
+
"graphMethod": "GET",
|
|
6205
|
+
"graphPathTemplate": "{url}",
|
|
6206
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/message-get",
|
|
6207
|
+
"options": [
|
|
6208
|
+
{
|
|
6209
|
+
"name": "url",
|
|
6210
|
+
"key": "url",
|
|
6211
|
+
"required": true,
|
|
6212
|
+
"description": "Outlook web URL for a single mail message. Accepted hosts: `outlook.office.com`, `outlook.office365.com`, `outlook.live.com`. Accepted shapes: OWA query-style (`/owa/?itemid=AAMkA...` or `/owa/?ItemID=AAMkA...`), modern path-style (`/mail/inbox/id/AAMkA...`), legacy short (`/mail/AAMkA...`). Calendar links (`/calendar/item/...` or `?path=/calendar/item`) are rejected with `cli_reject_calendar_link_on_mail_resolver` — use `resolve-calendar-link` for those."
|
|
6213
|
+
}
|
|
6214
|
+
],
|
|
6215
|
+
"example": "ask-marcel resolve-mail-link --url 'https://outlook.office.com/mail/inbox/id/AAMkAGI2THVS...'",
|
|
6216
|
+
"responseShape": "`{ messageId: string }`. `messageId` is URL-decoded and ready to pass to `get-mail-message --message-id <id>` or `convert-mail-to-markdown --message-id <id>`."
|
|
6217
|
+
},
|
|
6218
|
+
{
|
|
6219
|
+
"name": "resolve-teams-link",
|
|
6220
|
+
"summary": "Parse a Microsoft Teams `Copy link` URL (the share link emitted by the message context menu in Teams) into its `chatId` + `messageId` components. Pure transformation — no Graph call. Pipe the result into `get-teams-chat-message` to fetch the message body, or into `list-teams-chat-history` to read the chat that contains it.",
|
|
6221
|
+
"category": "chats",
|
|
6222
|
+
"graphMethod": "GET",
|
|
6223
|
+
"graphPathTemplate": "{url}",
|
|
6224
|
+
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/chatmessage-get",
|
|
6225
|
+
"options": [
|
|
6226
|
+
{
|
|
6227
|
+
"name": "url",
|
|
6228
|
+
"key": "url",
|
|
6229
|
+
"required": true,
|
|
6230
|
+
"description": "Teams message link, copied from Teams web/desktop via the message's `Copy link` action. Expected shape: `https://teams.microsoft.com/l/message/<url-encoded-chat-id>/<message-id>?tenantId=...&groupId=...&ctx=...`"
|
|
6231
|
+
}
|
|
6232
|
+
],
|
|
6233
|
+
"example": "ask-marcel resolve-teams-link --url 'https://teams.microsoft.com/l/message/19%3A...%40unq.gbl.spaces/1700000000000?tenantId=...&groupId=...&ctx=chat'",
|
|
6234
|
+
"responseShape": "`{ chatId: string, messageId: string, tenantId?: string, groupId?: string, parentMessageId?: string, context?: string }`. `chatId` and `messageId` are URL-decoded and ready to pass to other commands. Optional fields are included only when the source URL carried them."
|
|
6235
|
+
},
|
|
6031
6236
|
{
|
|
6032
6237
|
"name": "scopes-check",
|
|
6033
|
-
"summary": "Decode the cached Teams web client access token and return its scopes, audience, and expiry without making a Graph call. Use this as a self-test before running a command an LLM expects to fail with `accessDenied` — if the required scope isn't in the returned list, the call will reject regardless of tenant config. Each command's `scopesRequired` field in `help-json` lists the scopes that command needs; intersect with the array returned here for a pre-flight check (pipe both through `jq` and diff).",
|
|
6238
|
+
"summary": "Decode the cached Teams web client access token and return its scopes, audience, and expiry without making a Graph call. Use this as a self-test before running a command an LLM expects to fail with `accessDenied` — if the required scope isn't in the returned list, the call will reject regardless of tenant config. Each command's `scopesRequired` field in `help-json` lists the scopes that command needs; intersect with the array returned here for a pre-flight check (pipe both through `jq` and diff). The `expiresInSeconds` field (added Hervé-session §4) lets an LLM decide pre-emptively to `login` again — typically worth doing under ~5 minutes (300 s) so a long-running session doesn't hit the wall mid-command.",
|
|
6034
6239
|
"category": "meta",
|
|
6035
6240
|
"graphMethod": "GET",
|
|
6036
6241
|
"graphPathTemplate": "(meta) cached-token introspection — no Graph endpoint",
|
|
6037
6242
|
"graphDocsUrl": "https://learn.microsoft.com/en-us/graph/permissions-reference",
|
|
6038
6243
|
"options": [],
|
|
6039
6244
|
"example": "ask-marcel scopes-check",
|
|
6040
|
-
"responseShape": "{ scopes: string[], audience: string, expiresAt: string (ISO 8601) }"
|
|
6245
|
+
"responseShape": "`{ scopes: string[], audience: string, expiresAt: string (ISO 8601), expiresInSeconds: number }`. `expiresInSeconds` is negative when the cached token has already expired (run `login`); `audience` is the JWT `aud` claim (typically `https://graph.microsoft.com`)."
|
|
6041
6246
|
},
|
|
6042
6247
|
{
|
|
6043
6248
|
"name": "search-mail-messages",
|
|
6044
|
-
"summary": "Search the signed-in user's entire Outlook mailbox using KQL or free text. Results are ranked by Graph relevance. Note: Graph does not allow `$search` and `$filter` together — the CLI rejects `--filter` client-side with a pointer to `list-mail-messages` (which supports OData filtering). For sorting, server-side `$orderby` is also not allowed with `$search`; use the relevance ranking Graph returns.",
|
|
6249
|
+
"summary": "Search the signed-in user's entire Outlook mailbox using KQL or free text. Results are ranked by Graph relevance. The CLI ships a slim default `--select=id,subject,from,toRecipients,ccRecipients,receivedDateTime,hasAttachments,isRead,importance,bodyPreview` (same as `list-mail-messages`) so a 3-result page stays ~3 KB instead of ~30 KB. Pass `--select id,subject,body` to widen, or override entirely. Note: Graph does not allow `$search` and `$filter` together — the CLI rejects `--filter` client-side with a pointer to `list-mail-messages` (which supports OData filtering). For sorting, server-side `$orderby` is also not allowed with `$search`; use the relevance ranking Graph returns. **KQL quoting gotcha**: pass the raw KQL expression, e.g. `--query 'subject:invoice from:alice'`; do NOT wrap your terms in extra double-quotes (Graph then rejects with `BadRequest: An identifier was expected at position 0` because it sees `\"...\"` after the `$search=` interpolation). The CLI already wraps the entire `--query` value in `\"...\"` on the wire.",
|
|
6045
6250
|
"category": "mail",
|
|
6046
6251
|
"graphMethod": "GET",
|
|
6047
6252
|
"graphPathTemplate": "/me/messages?$search=\"{query}\"",
|
|
@@ -6091,7 +6296,7 @@
|
|
|
6091
6296
|
}
|
|
6092
6297
|
],
|
|
6093
6298
|
"example": "ask-marcel search-mail-messages --query 'from:alice subject:Q3'",
|
|
6094
|
-
"responseShape": "collection of Microsoft Graph `message` resources under `value[]`, ranked by relevance",
|
|
6299
|
+
"responseShape": "collection of Microsoft Graph `message` resources under `value[]`, ranked by relevance, each projected to the default `--select` set (or the requested fields when overridden). The default omits `body`, `internetMessageHeaders`, and `uniqueBody`.",
|
|
6095
6300
|
"pagination": true
|
|
6096
6301
|
},
|
|
6097
6302
|
{
|