ask-marcel-office-cli 1.5.2 → 2.1.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 (38) hide show
  1. package/CHANGELOG.md +133 -3
  2. package/README.md +23 -59
  3. package/dist/cli.js +1757 -1766
  4. package/dist/commands.json +437 -275
  5. package/dist/composition/build-deps.d.ts +7 -8
  6. package/dist/composition/cli.d.ts +5 -4
  7. package/dist/domain/iso-datetime.d.ts +1 -1
  8. package/dist/index.js +1606 -1653
  9. package/dist/infra/auth.d.ts +37 -21
  10. package/dist/infra/browser-auth.d.ts +13 -12
  11. package/dist/infra/graph-client.d.ts +28 -2
  12. package/dist/presenter/error-hints.d.ts +9 -9
  13. package/dist/use-cases/commands/build-command.d.ts +1 -1
  14. package/dist/use-cases/commands/command-types.d.ts +5 -5
  15. package/dist/use-cases/commands/convert-local-file.d.ts +4 -0
  16. package/dist/use-cases/commands/create-forward-draft.d.ts +12 -0
  17. package/dist/use-cases/commands/create-reply-draft.d.ts +10 -0
  18. package/dist/use-cases/commands/docs.d.ts +1 -1
  19. package/dist/use-cases/commands/get-schedule.d.ts +11 -0
  20. package/dist/use-cases/commands/graph-scopes.d.ts +1 -1
  21. package/dist/use-cases/commands/image-extraction.d.ts +2 -1
  22. package/dist/use-cases/commands/iso-datetime-schema.d.ts +1 -1
  23. package/dist/use-cases/commands/login-status.d.ts +31 -0
  24. package/dist/use-cases/commands/login.d.ts +3 -1
  25. package/dist/use-cases/commands/markdown-pipeline.d.ts +5 -5
  26. package/dist/use-cases/commands/option-descriptions.d.ts +1 -1
  27. package/dist/use-cases/commands/output-path.d.ts +4 -4
  28. package/dist/use-cases/commands/parse-recipients.d.ts +14 -0
  29. package/dist/use-cases/commands/zip-archive-to-markdown.d.ts +4 -2
  30. package/dist/use-cases/ports/filesystem.d.ts +1 -1
  31. package/docs/COMMANDS.md +16 -13
  32. package/docs/USAGE.md +23 -23
  33. package/package.json +3 -4
  34. package/dist/composition/env.d.ts +0 -2
  35. package/dist/infra/system-browser-auth.d.ts +0 -35
  36. package/dist/infra/system-browser-loader.d.ts +0 -3
  37. package/dist/infra/token-callback-server.d.ts +0 -31
  38. package/docs/commands.json +0 -7676
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "package": "ask-marcel-office-cli",
3
- "version": "1.5.2",
4
- "generatedAt": "2026-06-23T11:35:14.255Z",
3
+ "version": "2.1.0",
4
+ "generatedAt": "2026-07-13T10:43:42.181Z",
5
5
  "commands": [
6
6
  {
7
7
  "name": "convert-calendar-event-attachment-to-markdown",
@@ -37,7 +37,7 @@
37
37
  }
38
38
  }
39
39
  ],
40
- "example": "ask-marcel convert-calendar-event-attachment-to-markdown --event-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
40
+ "example": "ask-marcel-office convert-calendar-event-attachment-to-markdown --event-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
41
41
  "responseShape": "`{ contentType: \"text/markdown\", size, text }` on success (file/reference attachments converted via Graph + turndown; itemAttachment rendered locally). Plain-text source extensions return the raw-bytes envelope; unsupported types return an api_error with status 400.",
42
42
  "producesBytes": true
43
43
  },
@@ -62,7 +62,7 @@
62
62
  "description": "Attachment ID inside that event. Returned by `list-calendar-event-attachments`."
63
63
  }
64
64
  ],
65
- "example": "ask-marcel convert-calendar-event-attachment-to-pdf --event-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1' --output-path ./deck.pdf",
65
+ "example": "ask-marcel-office convert-calendar-event-attachment-to-pdf --event-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1' --output-path ./deck.pdf",
66
66
  "responseShape": "`{ contentType: \"application/pdf\", size, base64 }` — the PDF bytes, inlined. Plain-text and pdf sources short-circuit to `{ contentType, size, base64, note }`; image attachments return api_error 415; itemAttachment returns api_error 400. Pair with the global `--output-path` to land the bytes on disk and replace `base64` with `savedTo`.",
67
67
  "producesBytes": true
68
68
  },
@@ -78,7 +78,7 @@
78
78
  "name": "drive-id",
79
79
  "key": "driveId",
80
80
  "required": true,
81
- "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."
81
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
82
82
  },
83
83
  {
84
84
  "name": "item-id",
@@ -100,7 +100,7 @@
100
100
  }
101
101
  }
102
102
  ],
103
- "example": "ask-marcel convert-drive-item-zip --drive-id 'b!1234' --item-id '01ABC'",
103
+ "example": "ask-marcel-office convert-drive-item-zip --drive-id 'b!1234' --item-id '01ABC'",
104
104
  "responseShape": "`{ count, files: [{ path, contentType, size, text }] }` — one entry per file in the archive (sorted by path). Convertible files carry `{ contentType, size, text }` (the markdown); unsupported / failed entries carry `{ path, note }` instead. When the archive has more than 100 entries the response adds `truncated: true` + `totalEntries` and only the first 100 are converted."
105
105
  },
106
106
  {
@@ -143,6 +143,19 @@
143
143
  ]
144
144
  }
145
145
  },
146
+ {
147
+ "name": "include-images",
148
+ "key": "includeImages",
149
+ "required": false,
150
+ "description": "Pass `--include-images true` (a `.zip` only) to also extract each archive entry’s embedded images (docx/xlsx/pptx OOXML media parts, pdf page images) — every entry gains an `images: [{ path, contentType, sizeBytes, base64 }]` array (the same shape `extract-*-images` returns). Best-effort: an entry that carries no extractable images has no `images` key. Default `false`. Lets a caller OCR a secret pasted as a screenshot inside a zipped document.",
151
+ "argumentHint": {
152
+ "kind": "magicValue",
153
+ "values": [
154
+ "true",
155
+ "false"
156
+ ]
157
+ }
158
+ },
146
159
  {
147
160
  "name": "max-cells",
148
161
  "key": "maxCells",
@@ -150,8 +163,8 @@
150
163
  "description": "Per-sheet cell cap (positive integer; default 50 000) for xlsx/csv sources. A sheet whose used range exceeds the cap renders as a truncation hint instead of a multi-hundred-MB table. No-op on other sources."
151
164
  }
152
165
  ],
153
- "example": "ask-marcel convert-local-file --path ./report.docx",
154
- "responseShape": "`{ contentType: \"text/markdown\" | \"text/plain\", size, text }` for a single file; `{ count, files: [{ path, contentType, size, text } | { path, note }] }` for a `.zip` (one entry per contained file, unsupported entries noted). A missing file returns api_error 404 with the path. Pair with the global `--output-path` to land the markdown on disk.",
166
+ "example": "ask-marcel-office convert-local-file --path ./report.docx",
167
+ "responseShape": "`{ contentType: \"text/markdown\" | \"text/plain\", size, text }` for a single file; `{ count, files: [{ path, contentType, size, text } | { path, note }] }` for a `.zip` (one entry per contained file, unsupported entries noted). With `--include-images true` each `.zip` entry also carries `images: [{ path, contentType, sizeBytes, base64 }]` when it has extractable embedded images. A missing file returns api_error 404 with the path. Pair with the global `--output-path` to land the markdown on disk.",
155
168
  "producesBytes": true
156
169
  },
157
170
  {
@@ -188,7 +201,7 @@
188
201
  }
189
202
  }
190
203
  ],
191
- "example": "ask-marcel convert-mail-attachment-to-markdown --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
204
+ "example": "ask-marcel-office convert-mail-attachment-to-markdown --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
192
205
  "responseShape": "`{ contentType: \"text/markdown\", size, text }` on success (file/reference attachments converted via Graph + turndown; itemAttachment rendered locally). Plain-text source extensions return the raw-bytes envelope; unsupported types return an api_error with status 400.",
193
206
  "producesBytes": true
194
207
  },
@@ -213,7 +226,7 @@
213
226
  "description": "Attachment ID inside that message. Returned by `list-mail-attachments`."
214
227
  }
215
228
  ],
216
- "example": "ask-marcel convert-mail-attachment-to-pdf --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
229
+ "example": "ask-marcel-office convert-mail-attachment-to-pdf --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
217
230
  "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 source extensions and pdf sources short-circuit to `{ contentType, size, base64, note }` with their native bytes; itemAttachment returns api_error 400. Pair with the global `--output-path` to land the bytes on disk and replace `base64` with `savedTo` for multi-MB PDFs.",
218
231
  "producesBytes": true
219
232
  },
@@ -251,12 +264,12 @@
251
264
  }
252
265
  }
253
266
  ],
254
- "example": "ask-marcel convert-mail-attachment-zip --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
267
+ "example": "ask-marcel-office convert-mail-attachment-zip --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
255
268
  "responseShape": "`{ count, files: [{ path, contentType, size, text }] }` — one entry per file in the archive (sorted by path; non-mojibake names). Convertible files carry `{ contentType, size, text }` (the markdown); unsupported / failed entries carry `{ path, note }`. When the archive has more than 100 entries the response adds `truncated: true` + `totalEntries` and only the first 100 are converted. A non-fileAttachment (itemAttachment / referenceAttachment) or a non-zip payload returns an api_error."
256
269
  },
257
270
  {
258
271
  "name": "convert-mail-to-markdown",
259
- "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.",
272
+ "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: 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.",
260
273
  "category": "mail",
261
274
  "graphMethod": "GET",
262
275
  "graphPathTemplate": "/me/messages/{message-id}",
@@ -294,10 +307,63 @@
294
307
  }
295
308
  }
296
309
  ],
297
- "example": "ask-marcel convert-mail-to-markdown --message-id 'AAMkAD...'",
310
+ "example": "ask-marcel-office convert-mail-to-markdown --message-id 'AAMkAD...'",
298
311
  "responseShape": "`{ contentType: \"text/markdown\", size, text, note? }` — headers + turndown-rendered body + (when present) a file-attachments list. The optional `note` carries a partial-success hint when the attachments-metadata fetch fails after the body succeeded, and/or a flag that a quoted reply chain was stripped (use `--keep-quoted true` to include it).",
299
312
  "producesBytes": true
300
313
  },
314
+ {
315
+ "name": "create-forward-draft",
316
+ "summary": "Create an UNSENT forward draft of an existing message. POST /me/messages/{id}/createForward mints the draft (FW: subject, quoted original) with your comment placed above the quote and the recipients set, in one call. Redirects a thread to the right owner without leaving the CLI. The draft is saved in Drafts and can be reviewed, edited, and sent from any Outlook client; the CLI still cannot send.",
317
+ "category": "mail",
318
+ "graphMethod": "POST",
319
+ "graphPathTemplate": "/me/messages/{forward-message-id}/createForward (+ optional body-free PATCH for cc / subject)",
320
+ "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/message-createforward",
321
+ "options": [
322
+ {
323
+ "name": "forward-message-id",
324
+ "key": "forwardMessageId",
325
+ "required": true,
326
+ "aliases": [
327
+ {
328
+ "name": "id",
329
+ "key": "id"
330
+ }
331
+ ],
332
+ "description": "The message being forwarded. Source from list-mail-folder-messages or search-mail-messages. Accepts `--id` as an alias.",
333
+ "argumentHint": {
334
+ "kind": "idOrName"
335
+ }
336
+ },
337
+ {
338
+ "name": "to-recipients",
339
+ "key": "toRecipients",
340
+ "required": true,
341
+ "description": "Comma-separated list of recipient email addresses to forward to (e.g. \"alice@example.com,bob@example.com\"). Required: a forward without a recipient is not actionable."
342
+ },
343
+ {
344
+ "name": "cc-recipients",
345
+ "key": "ccRecipients",
346
+ "required": false,
347
+ "description": "Comma-separated list of CC recipient email addresses."
348
+ },
349
+ {
350
+ "name": "body-content",
351
+ "key": "bodyContent",
352
+ "required": true,
353
+ "description": "The comment text, placed above the quoted forwarded message by Graph."
354
+ },
355
+ {
356
+ "name": "subject",
357
+ "key": "subject",
358
+ "required": false,
359
+ "description": "Optional subject override. Omit to keep the inherited \"FW: ...\" subject."
360
+ }
361
+ ],
362
+ "example": "ask-marcel-office create-forward-draft --forward-message-id \"AAMkAD...\" --to-recipients \"bob@example.com\" --body-content \"Bob owns this now, forwarding for your action.\"",
363
+ "responseShape": "The updated draft message object (or `{ ok: true }` when Graph answers 204): `{ id, subject, body, toRecipients, ccRecipients, isDraft: true, … }`. The `id` is the draft - update further with update-mail-draft, or open Outlook Drafts to review and send.",
364
+ "bodyTemplate": "POST { comment: '{body-content}', toRecipients: '{to-recipients}' } then optional PATCH { ccRecipients?: '{cc-recipients}', subject?: '{subject}' }",
365
+ "mutates": true
366
+ },
301
367
  {
302
368
  "name": "create-mail-draft",
303
369
  "summary": "Create a new mail draft. POST /me/messages (or /me/mailFolders/{id}/messages when --mail-folder-id is set). The draft is saved in the Drafts folder (or the specified folder) and can be sent later via the Outlook client or Graph sendMail. Recipients are comma-separated email addresses. Returns the created message object with its id — use this id with update-mail-draft to modify the draft before sending.",
@@ -373,14 +439,55 @@
373
439
  }
374
440
  }
375
441
  ],
376
- "example": "ask-marcel create-mail-draft --subject \"Q3 Report\" --body-content \"Please review the attached report.\" --to-recipients \"alice@example.com,bob@example.com\" --importance High",
442
+ "example": "ask-marcel-office create-mail-draft --subject \"Q3 Report\" --body-content \"Please review the attached report.\" --to-recipients \"alice@example.com,bob@example.com\" --importance High",
377
443
  "responseShape": "The created Microsoft Graph message object: `{ id, subject, body, from, toRecipients, ccRecipients, bccRecipients, receivedDateTime, isDraft, … }`. The `id` field is the draft message ID — use it with `update-mail-draft` to modify before sending.",
378
444
  "bodyTemplate": "{ subject: '{subject}', body: { contentType: '{body-content-type}', content: '{body-content}' }, toRecipients: '{to-recipients}', ccRecipients: '{cc-recipients}', bccRecipients: '{bcc-recipients}', importance: '{importance}' }",
379
445
  "mutates": true
380
446
  },
447
+ {
448
+ "name": "create-reply-draft",
449
+ "summary": "Create an UNSENT reply-all draft threaded on an existing message. POST /me/messages/{id}/createReplyAll mints the draft (inherited recipients, RE: subject, quoted history) with your reply text placed above the quote, in one call. Reply-all by design - dropping recipients is a deliberate act for the human in Outlook, not a default. The draft is saved in Drafts and can be reviewed, edited, and sent from any Outlook client; the CLI still cannot send.",
450
+ "category": "mail",
451
+ "graphMethod": "POST",
452
+ "graphPathTemplate": "/me/messages/{reply-to-message-id}/createReplyAll (+ optional body-free PATCH for subject)",
453
+ "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/message-createreplyall",
454
+ "options": [
455
+ {
456
+ "name": "reply-to-message-id",
457
+ "key": "replyToMessageId",
458
+ "required": true,
459
+ "aliases": [
460
+ {
461
+ "name": "id",
462
+ "key": "id"
463
+ }
464
+ ],
465
+ "description": "The message being replied to. Source from list-mail-folder-messages or search-mail-messages. Accepts `--id` as an alias.",
466
+ "argumentHint": {
467
+ "kind": "idOrName"
468
+ }
469
+ },
470
+ {
471
+ "name": "body-content",
472
+ "key": "bodyContent",
473
+ "required": true,
474
+ "description": "The reply text, placed above the quoted history by Graph."
475
+ },
476
+ {
477
+ "name": "subject",
478
+ "key": "subject",
479
+ "required": false,
480
+ "description": "Optional subject override. Omit to keep the inherited \"RE: ...\" subject."
481
+ }
482
+ ],
483
+ "example": "ask-marcel-office create-reply-draft --reply-to-message-id \"AAMkAD...\" --body-content \"Confirmed for Concur, aligned with the group choice.\"",
484
+ "responseShape": "The updated draft message object (or `{ ok: true }` when Graph answers 204): `{ id, subject, body, toRecipients, ccRecipients, isDraft: true, … }`. The `id` is the draft - update further with update-mail-draft, or open Outlook Drafts to review and send.",
485
+ "bodyTemplate": "POST { comment: '{body-content}' } then optional PATCH { subject?: '{subject}' }",
486
+ "mutates": true
487
+ },
381
488
  {
382
489
  "name": "download-drive-item-as-markdown",
383
- "summary": "Download a OneDrive / SharePoint file converted to markdown via local conversion pipelines. Supported: docx (mammoth → turndown; embedded images are replaced with `[image]` placeholders by default — pass `--inline-images true` to embed them as base64 `data:` URIs, or pull the full-resolution originals with `extract-drive-item-images`; tables become GFM pipe tables), xlsx (one markdown table per sheet via sheetjs; any sheet whose used range exceeds the `--max-cells` cap, default 50 000, is summarised with a band-by-band read hint instead of a multi-hundred-MB table), csv (rendered as a markdown table), odt/ods/odp (OpenDocument body walked from content.xml — headings, lists, tables, named sheets, per-slide text, including style-hidden content), plus plain-text passthrough (txt/md/html/json/yaml/log/xml/etc.) — the bytes are followed through any CDN redirect and returned inline as `{ contentType: \"text/plain\", size, text }` so the LLM never needs a separate fetch step. Loop/Fluid/Whiteboard files use Graph `?format=html` (the four inputs Microsoft documents — https://learn.microsoft.com/en-us/graph/api/driveitem-get-content-format). pptx is flattened to per-slide text (titles, bullets, text-box / table text, with speaker notes inline) as `## Slide N` sections — document order, not guaranteed visual order; for layout / images / charts, `download-drive-item-as-pdf` + a vision-capable LLM reads the rendered deck better. pdf has its text layer extracted locally (via unpdf) and returned as `{ contentType: \"text/plain\", size, text }`; a scanned / image-only PDF with no text layer points you at `download-drive-item-as-pdf` + a vision model. Legacy OLE Office: .xls (Excel 97-2003) is read by sheetjs (same markdown-table path as .xlsx); .doc (Word 97-2003) is extracted by word-extractor as plain text (body only, no structure); .ppt (PowerPoint 97-2003) has no pure-JS path — use `download-drive-item-as-pdf` first, then a vision model. Outlook .msg (a saved email, also an OLE container) is rendered to markdown — an H1 subject, a From/To/Cc/Date header block, the message body, then an `## Attachments` section where each attachment is converted recursively through this same pipeline (the same way a .zip is unpacked); inline / image attachments are listed with a note. For rtf/etc. use `download-drive-item-as-pdf` — Graph `?format=pdf` accepts 38 input extensions.",
490
+ "summary": "Download a OneDrive / SharePoint file converted to markdown via local conversion pipelines. Supported: docx (mammoth → turndown; embedded images are replaced with `[image]` placeholders by default — pass `--inline-images true` to embed them as base64 `data:` URIs, or pull the full-resolution originals with `extract-drive-item-images`; tables become GFM pipe tables), xlsx (one markdown table per sheet via sheetjs; any sheet whose used range exceeds the `--max-cells` cap, default 50 000, is summarised with a band-by-band read hint instead of a multi-hundred-MB table), csv (rendered as a markdown table), odt/ods/odp (OpenDocument body walked from content.xml — headings, lists, tables, named sheets, per-slide text, including style-hidden content), plus plain-text passthrough (txt/md/html/json/yaml/log/xml/etc.) — the bytes are followed through any CDN redirect and returned inline as `{ contentType: \"text/plain\", size, text }` so the LLM never needs a separate fetch step. Loop/Fluid/Whiteboard files use Graph `?format=html` (the four inputs Microsoft documents — https://learn.microsoft.com/en-us/graph/api/driveitem-get-content-format). To locate `.loop` pages to convert, run `microsoft-search-query` with `filetype:loop` and pass the `resource.id` and `parentReference.driveId` from each hit here. pptx is flattened to per-slide text (titles, bullets, text-box / table text, with speaker notes inline) as `## Slide N` sections — document order, not guaranteed visual order; for layout / images / charts, `download-drive-item-as-pdf` + a vision-capable LLM reads the rendered deck better. pdf has its text layer extracted locally (via unpdf) and returned as `{ contentType: \"text/plain\", size, text }`; a scanned / image-only PDF with no text layer points you at `download-drive-item-as-pdf` + a vision model. Legacy OLE Office: .xls (Excel 97-2003) is read by sheetjs (same markdown-table path as .xlsx); .doc (Word 97-2003) is extracted by word-extractor as plain text (body only, no structure); .ppt (PowerPoint 97-2003) has no pure-JS path — use `download-drive-item-as-pdf` first, then a vision model. Outlook .msg (a saved email, also an OLE container) is rendered to markdown — an H1 subject, a From/To/Cc/Date header block, the message body, then an `## Attachments` section where each attachment is converted recursively through this same pipeline (the same way a .zip is unpacked); inline / image attachments are listed with a note. For rtf/etc. use `download-drive-item-as-pdf` — Graph `?format=pdf` accepts 38 input extensions.",
384
491
  "category": "drive",
385
492
  "graphMethod": "GET",
386
493
  "graphPathTemplate": "/drives/{drive-id}/items/{item-id}/content?format=html",
@@ -390,7 +497,7 @@
390
497
  "name": "drive-id",
391
498
  "key": "driveId",
392
499
  "required": true,
393
- "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."
500
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
394
501
  },
395
502
  {
396
503
  "name": "item-id",
@@ -431,7 +538,7 @@
431
538
  "description": "Per-sheet cell cap (positive integer; default 50 000) for xlsx sources. A worksheet whose used range (rows × cols) exceeds the cap is rendered as its `## SheetName` header plus a one-line hint pointing at `get-excel-used-range` / `get-excel-range` for band-by-band reads, instead of a full markdown table — a genuinely dense 49 MB workbook otherwise builds a multi-hundred-MB string and OOMs the process. Raise it to force a larger render. No-op on non-xlsx sources."
432
539
  }
433
540
  ],
434
- "example": "ask-marcel download-drive-item-as-markdown --drive-id 'b!1234' --item-id '01ABC'",
541
+ "example": "ask-marcel-office download-drive-item-as-markdown --drive-id 'b!1234' --item-id '01ABC'",
435
542
  "responseShape": "`{ contentType: \"text/markdown\", size: <chars>, text: \"...\" }` for the locally-converted case (docx/xlsx/csv/.msg); `{ contentType: \"text/plain\", size, text }` for plain-text passthrough sources (txt/md/html/etc.) — bytes are inlined whether Graph returns them directly or via a CDN redirect that the CLI follows internally.",
436
543
  "producesBytes": true
437
544
  },
@@ -447,7 +554,7 @@
447
554
  "name": "drive-id",
448
555
  "key": "driveId",
449
556
  "required": true,
450
- "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."
557
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
451
558
  },
452
559
  {
453
560
  "name": "item-id",
@@ -456,7 +563,7 @@
456
563
  "description": "driveItem ID of the file to convert. Returned by `list-folder-files` or `search-onedrive-files`."
457
564
  }
458
565
  ],
459
- "example": "ask-marcel download-drive-item-as-pdf --drive-id 'b!1234' --item-id '01ABC'",
566
+ "example": "ask-marcel-office download-drive-item-as-pdf --drive-id 'b!1234' --item-id '01ABC'",
460
567
  "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.",
461
568
  "producesBytes": true
462
569
  },
@@ -475,22 +582,22 @@
475
582
  "name": "drive-id",
476
583
  "key": "driveId",
477
584
  "required": true,
478
- "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."
585
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
479
586
  },
480
587
  {
481
588
  "name": "item-id",
482
589
  "key": "itemId",
483
590
  "required": true,
484
- "description": "driveItem ID of the file to download. Returned by `ask-marcel list-folder-files` (works on SharePoint library drives too) or `search-onedrive-files`."
591
+ "description": "driveItem ID of the file to download. Returned by `ask-marcel-office list-folder-files` (works on SharePoint library drives too) or `search-onedrive-files`."
485
592
  }
486
593
  ],
487
- "example": "ask-marcel download-drive-item-content --drive-id 'b!1234' --item-id '01ABC'",
594
+ "example": "ask-marcel-office download-drive-item-content --drive-id 'b!1234' --item-id '01ABC'",
488
595
  "responseShape": "`{ contentType: \"text/plain\", size, text }` when the bytes decode as valid UTF-8; `{ contentType, size, base64 }` otherwise (binary, or non-UTF-8-encoded text). Pair with the global `--output-path <path>` flag to land the bytes on disk and replace the inline field with `savedTo` for multi-MB files.",
489
596
  "producesBytes": true
490
597
  },
491
598
  {
492
599
  "name": "download-drive-item-version",
493
- "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-drive-item-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, odt/ods/odp via content.xml, 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).",
600
+ "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-drive-item-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, odt/ods/odp via content.xml, 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. 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).",
494
601
  "category": "drive",
495
602
  "graphMethod": "GET",
496
603
  "graphPathTemplate": "/drives/{drive-id}/items/{item-id}/versions/{version-id}/content",
@@ -500,7 +607,7 @@
500
607
  "name": "drive-id",
501
608
  "key": "driveId",
502
609
  "required": true,
503
- "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."
610
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
504
611
  },
505
612
  {
506
613
  "name": "item-id",
@@ -512,7 +619,7 @@
512
619
  "name": "version-id",
513
620
  "key": "versionId",
514
621
  "required": true,
515
- "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."
622
+ "description": "driveItemVersion ID. Returned by `ask-marcel-office 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."
516
623
  },
517
624
  {
518
625
  "name": "format",
@@ -542,7 +649,7 @@
542
649
  }
543
650
  }
544
651
  ],
545
- "example": "ask-marcel download-drive-item-version --drive-id 'b!1234' --item-id '01ABC' --version-id '4.0' --format pdf",
652
+ "example": "ask-marcel-office download-drive-item-version --drive-id 'b!1234' --item-id '01ABC' --version-id '4.0' --format pdf",
546
653
  "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.",
547
654
  "producesBytes": true,
548
655
  "needsElevatedToken": true
@@ -559,7 +666,7 @@
559
666
  "name": "drive-id",
560
667
  "key": "driveId",
561
668
  "required": true,
562
- "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."
669
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
563
670
  },
564
671
  {
565
672
  "name": "item-id",
@@ -568,7 +675,7 @@
568
675
  "description": "driveItem ID of the pdf / docx / xlsx / pptx file. Returned by `list-folder-files` or `search-onedrive-files`."
569
676
  }
570
677
  ],
571
- "example": "ask-marcel extract-drive-item-images --drive-id 'b!1234' --item-id '01ABC' --output-dir ./deck-images",
678
+ "example": "ask-marcel-office extract-drive-item-images --drive-id 'b!1234' --item-id '01ABC' --output-dir ./deck-images",
572
679
  "responseShape": "`{ count, media: [{ path, contentType, sizeBytes, base64 }] }`. `path` is the source part path — `ppt/media/image3.png` for OOXML, `pdf/page2/<key>.png` for PDF (every PDF image is re-encoded as PNG). Pair with the global `--output-dir <dir>` to write each image to that folder — the response then replaces each `base64` with `savedTo: <dir>/<filename>` (the part path is flattened, e.g. `pdf_page2_Im0.png`). `count: 0` with an empty `media` array means the document embeds no extractable images (after the emf/wmf/audio/video filter).",
573
680
  "producesMedia": true
574
681
  },
@@ -587,7 +694,7 @@
587
694
  "description": "Filesystem path of the pdf / docx / xlsx / pptx file to extract from (absolute, or relative to the current working directory). E.g. `/tmp/deck.pdf`, `./report.docx`."
588
695
  }
589
696
  ],
590
- "example": "ask-marcel extract-local-file-images --path /tmp/deck.pdf --output-dir ./deck-images",
697
+ "example": "ask-marcel-office extract-local-file-images --path /tmp/deck.pdf --output-dir ./deck-images",
591
698
  "responseShape": "`{ count, media: [{ path, contentType, sizeBytes, base64 }] }`. `path` is the source part path — `ppt/media/image3.png` for OOXML, `pdf/page2/<key>.png` for PDF (every PDF image is re-encoded as PNG). Pair with the global `--output-dir <dir>` to write each image to that folder — the response then replaces each `base64` with `savedTo: <dir>/<filename>` (the part path is flattened, e.g. `pdf_page2_Im0.png`). `count: 0` with an empty `media` array means the document embeds no extractable images (after the emf/wmf/audio/video filter). A missing file returns api_error 404 with the path.",
592
699
  "producesMedia": true
593
700
  },
@@ -612,7 +719,7 @@
612
719
  "description": "Attachment ID inside that message. Returned by `list-mail-attachments`."
613
720
  }
614
721
  ],
615
- "example": "ask-marcel extract-mail-attachment-images --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1' --output-dir ./att-images",
722
+ "example": "ask-marcel-office extract-mail-attachment-images --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1' --output-dir ./att-images",
616
723
  "responseShape": "`{ count, media: [{ path, contentType, sizeBytes, base64 }] }`. `path` is the in-package part path (e.g. `ppt/media/image3.png`). Pair with the global `--output-dir <dir>` to write each image to that folder — the response then replaces each `base64` with `savedTo` (the part path is flattened, e.g. `pdf_page2_Im0.png`). `count: 0` means the attachment embeds no extractable images (after the emf/wmf/audio/video filter).",
617
724
  "producesMedia": true
618
725
  },
@@ -628,7 +735,7 @@
628
735
  "name": "drive-id",
629
736
  "key": "driveId",
630
737
  "required": true,
631
- "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."
738
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
632
739
  },
633
740
  {
634
741
  "name": "item-id",
@@ -637,7 +744,7 @@
637
744
  "description": "driveItem ID of the .docx/.xlsx/.pptx or .odt/.ods/.odp file. Returned by `list-folder-files` or `search-onedrive-files`."
638
745
  }
639
746
  ],
640
- "example": "ask-marcel extract-sharepoint-links-in-documents --drive-id 'b!1234' --item-id '01ABC'",
747
+ "example": "ask-marcel-office extract-sharepoint-links-in-documents --drive-id 'b!1234' --item-id '01ABC'",
641
748
  "responseShape": "`{ driveId, itemId, links: [{ url, driveId, itemId, name, webUrl } | { url, error }], truncated, skippedCount }` — one entry per unique SharePoint URL found in the document’s external relationships."
642
749
  },
643
750
  {
@@ -661,12 +768,12 @@
661
768
  "description": "Outlook message ID. Returned by `list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
662
769
  }
663
770
  ],
664
- "example": "ask-marcel extract-sharepoint-links-in-mail --message-id 'AAMkADk0...'",
771
+ "example": "ask-marcel-office extract-sharepoint-links-in-mail --message-id 'AAMkADk0...'",
665
772
  "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."
666
773
  },
667
774
  {
668
775
  "name": "find-chats-with-user",
669
- "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 Jane` matches `Jane DOE` AND `jane.doe@example.com` AND `JANE` — 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). Cross-tenant resolution: the summary roster returns externally-homed counterparts as a bare object-id (no name/email), which a name search cannot match; for every bare DIRECT (1:1) chat the command hydrates the roster via the per-chat members endpoint and re-matches — so an external counterpart who is bare in your 1:1 is still found, even when they were already resolved in some meeting (the dual-identity case). Bare members in group/meeting chats are not deep-probed; when nothing matches and such members exist it returns a `hint` plus `unresolvedMemberCount` rather than a confident empty result. **Best-effort, may break on Microsoft client updates** — the chat substrate is not in the public Microsoft Graph API.",
776
+ "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 Alex` matches `Alex Kim` AND `alex.kim@example.com` AND `ALEX` — 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). Cross-tenant resolution: the summary roster returns externally-homed counterparts as a bare object-id (no name/email), which a name search cannot match; for every bare DIRECT (1:1) chat the command hydrates the roster via the per-chat members endpoint and re-matches — so an external counterpart who is bare in your 1:1 is still found, even when they were already resolved in some meeting (the dual-identity case). Bare members in group/meeting chats are not deep-probed; when nothing matches and such members exist it returns a `hint` plus `unresolvedMemberCount` rather than a confident empty result. **Best-effort, may break on Microsoft client updates** — the chat substrate is not in the public Microsoft Graph API.",
670
777
  "category": "chats",
671
778
  "graphMethod": "GET",
672
779
  "graphPathTemplate": "https://teams.microsoft.com/api/csa/{region}/api/v3/teams/users/me/chats",
@@ -676,7 +783,7 @@
676
783
  "name": "name",
677
784
  "key": "name",
678
785
  "required": true,
679
- "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 `Jane` ↔ `Jane` ↔ `JANE` 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."
786
+ "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 `Alex` ↔ `Alex` ↔ `ALEX` 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."
680
787
  },
681
788
  {
682
789
  "name": "max-pages",
@@ -691,7 +798,7 @@
691
798
  "description": "Chats per page (positive integer; default 100, same value Teams web uses). Server may silently cap."
692
799
  }
693
800
  ],
694
- "example": "ask-marcel find-chats-with-user --name 'Jane DOE'",
801
+ "example": "ask-marcel-office find-chats-with-user --name 'Alex Kim'",
695
802
  "responseShape": "`{ name, matches: [{ chatId, title, chatType, threadType, memberCount, lastMessageAt?, matchedMembers: [{ mri, displayName, email, userSubType }] }], matchCount, pagesFetched, chatsScanned, chatsHydrated, unresolvedMemberCount, hasMore, nextContinuationToken?, hint? }`. `matchedMembers` always carries the matching entries' identifying fields — pass `chatId` into `list-teams-chat-history` to read message bodies. `chatsHydrated` counts the per-chat members lookups spent resolving bare cross-tenant members in direct (1:1) chats. `unresolvedMemberCount` is how many cross-tenant members are still unresolved by name (bare members in group/meeting chats, which are not deep-probed, plus any 1:1 hydration that errored); when `matchCount` is 0 and this is non-zero, a `hint` is present explaining the likely cause and the object-id / read-by-chat-id remedy — so an empty result is never silently confident. `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`).",
696
803
  "needsSubstrateToken": true,
697
804
  "stability": "experimental"
@@ -714,7 +821,7 @@
714
821
  "key": "id"
715
822
  }
716
823
  ],
717
- "description": "Microsoft Graph event ID. Returned by `ask-marcel list-calendar-events` in the `id` field of each event."
824
+ "description": "Microsoft Graph event ID. Returned by `ask-marcel-office list-calendar-events` in the `id` field of each event."
718
825
  },
719
826
  {
720
827
  "name": "select",
@@ -729,7 +836,7 @@
729
836
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
730
837
  }
731
838
  ],
732
- "example": "ask-marcel get-calendar-event --event-id 'AAMkAGI2THVS...' --select id,subject,start,end,attendees",
839
+ "example": "ask-marcel-office get-calendar-event --event-id 'AAMkAGI2THVS...' --select id,subject,start,end,attendees",
733
840
  "responseShape": "single Microsoft Graph `event` resource (or projection of the requested `--select` fields)"
734
841
  },
735
842
  {
@@ -765,7 +872,7 @@
765
872
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
766
873
  }
767
874
  ],
768
- "example": "ask-marcel get-channel-files-folder --team-id 'tm1' --channel-id 'ch1'",
875
+ "example": "ask-marcel-office get-channel-files-folder --team-id 'tm1' --channel-id 'ch1'",
769
876
  "responseShape": "single Microsoft Graph `driveItem` resource (folder)"
770
877
  },
771
878
  {
@@ -801,7 +908,7 @@
801
908
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
802
909
  }
803
910
  ],
804
- "example": "ask-marcel get-chat --chat-id '19:abc...@thread.v2'",
911
+ "example": "ask-marcel-office get-chat --chat-id '19:abc...@thread.v2'",
805
912
  "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.",
806
913
  "needsElevatedToken": true
807
914
  },
@@ -826,7 +933,7 @@
826
933
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
827
934
  }
828
935
  ],
829
- "example": "ask-marcel get-current-user",
936
+ "example": "ask-marcel-office get-current-user",
830
937
  "responseShape": "single Microsoft Graph `user` resource projected to the default `--select` set (or, when overridden, to the requested fields)"
831
938
  },
832
939
  {
@@ -841,7 +948,7 @@
841
948
  "name": "drive-id",
842
949
  "key": "driveId",
843
950
  "required": true,
844
- "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."
951
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
845
952
  },
846
953
  {
847
954
  "name": "item-id",
@@ -886,7 +993,7 @@
886
993
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
887
994
  }
888
995
  ],
889
- "example": "ask-marcel get-drive-delta --drive-id 'b!1234' --item-id '01ROOT'",
996
+ "example": "ask-marcel-office get-drive-delta --drive-id 'b!1234' --item-id '01ROOT'",
890
997
  "responseShape": "collection of changed Microsoft Graph `driveItem` resources under `data.value[]`. Cursor tokens are hoisted to envelope level: top-level `nextLink` while paging, then top-level `deltaLink` on the final page.",
891
998
  "pagination": true
892
999
  },
@@ -902,7 +1009,7 @@
902
1009
  "name": "drive-id",
903
1010
  "key": "driveId",
904
1011
  "required": true,
905
- "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."
1012
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
906
1013
  },
907
1014
  {
908
1015
  "name": "item-id",
@@ -923,7 +1030,7 @@
923
1030
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
924
1031
  }
925
1032
  ],
926
- "example": "ask-marcel get-drive-item --drive-id 'b!1234' --item-id '01ABC' --select 'id,name,size,lastModifiedDateTime'",
1033
+ "example": "ask-marcel-office get-drive-item --drive-id 'b!1234' --item-id '01ABC' --select 'id,name,size,lastModifiedDateTime'",
927
1034
  "responseShape": "single Microsoft Graph `driveItem` resource"
928
1035
  },
929
1036
  {
@@ -938,7 +1045,7 @@
938
1045
  "name": "drive-id",
939
1046
  "key": "driveId",
940
1047
  "required": true,
941
- "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."
1048
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
942
1049
  },
943
1050
  {
944
1051
  "name": "item-id",
@@ -947,7 +1054,7 @@
947
1054
  "description": "driveItem ID."
948
1055
  }
949
1056
  ],
950
- "example": "ask-marcel get-drive-item-analytics --drive-id 'b!1234' --item-id '01ABC'",
1057
+ "example": "ask-marcel-office get-drive-item-analytics --drive-id 'b!1234' --item-id '01ABC'",
951
1058
  "responseShape": "single Microsoft Graph `itemAnalytics` resource"
952
1059
  },
953
1060
  {
@@ -962,7 +1069,7 @@
962
1069
  "name": "drive-id",
963
1070
  "key": "driveId",
964
1071
  "required": true,
965
- "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."
1072
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
966
1073
  },
967
1074
  {
968
1075
  "name": "item-id",
@@ -983,7 +1090,7 @@
983
1090
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
984
1091
  }
985
1092
  ],
986
- "example": "ask-marcel get-drive-item-created-by-user --drive-id 'b!1234' --item-id '01ABC' --select 'id,displayName,jobTitle,mail'",
1093
+ "example": "ask-marcel-office get-drive-item-created-by-user --drive-id 'b!1234' --item-id '01ABC' --select 'id,displayName,jobTitle,mail'",
987
1094
  "responseShape": "single Microsoft Graph `user` resource"
988
1095
  },
989
1096
  {
@@ -998,7 +1105,7 @@
998
1105
  "name": "drive-id",
999
1106
  "key": "driveId",
1000
1107
  "required": true,
1001
- "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."
1108
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1002
1109
  },
1003
1110
  {
1004
1111
  "name": "item-id",
@@ -1019,7 +1126,7 @@
1019
1126
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1020
1127
  }
1021
1128
  ],
1022
- "example": "ask-marcel get-drive-item-last-modified-by-user --drive-id 'b!1234' --item-id '01ABC' --select 'id,displayName,mail'",
1129
+ "example": "ask-marcel-office get-drive-item-last-modified-by-user --drive-id 'b!1234' --item-id '01ABC' --select 'id,displayName,mail'",
1023
1130
  "responseShape": "single Microsoft Graph `user` resource"
1024
1131
  },
1025
1132
  {
@@ -1034,7 +1141,7 @@
1034
1141
  "name": "drive-id",
1035
1142
  "key": "driveId",
1036
1143
  "required": true,
1037
- "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."
1144
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1038
1145
  },
1039
1146
  {
1040
1147
  "name": "item-id",
@@ -1055,7 +1162,7 @@
1055
1162
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1056
1163
  }
1057
1164
  ],
1058
- "example": "ask-marcel get-drive-item-list-item --drive-id 'b!1234' --item-id '01ABC'",
1165
+ "example": "ask-marcel-office get-drive-item-list-item --drive-id 'b!1234' --item-id '01ABC'",
1059
1166
  "responseShape": "single Microsoft Graph `listItem` resource"
1060
1167
  },
1061
1168
  {
@@ -1097,7 +1204,7 @@
1097
1204
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1098
1205
  }
1099
1206
  ],
1100
- "example": "ask-marcel get-drive-root-delta",
1207
+ "example": "ask-marcel-office get-drive-root-delta",
1101
1208
  "responseShape": "collection of Microsoft Graph `driveItem` resources under `data.value[]`. Cursor tokens are hoisted to envelope level: top-level `nextLink` while paging, then top-level `deltaLink` on the final page.",
1102
1209
  "pagination": true
1103
1210
  },
@@ -1119,7 +1226,7 @@
1119
1226
  "key": "id"
1120
1227
  }
1121
1228
  ],
1122
- "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."
1229
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1123
1230
  },
1124
1231
  {
1125
1232
  "name": "select",
@@ -1134,7 +1241,7 @@
1134
1241
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1135
1242
  }
1136
1243
  ],
1137
- "example": "ask-marcel get-drive-root-item --drive-id 'b!1234'",
1244
+ "example": "ask-marcel-office get-drive-root-item --drive-id 'b!1234'",
1138
1245
  "responseShape": "single Microsoft Graph `driveItem` resource (the root folder)"
1139
1246
  },
1140
1247
  {
@@ -1164,7 +1271,7 @@
1164
1271
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1165
1272
  }
1166
1273
  ],
1167
- "example": "ask-marcel get-drive-special-folder --folder-name 'documents'",
1274
+ "example": "ask-marcel-office get-drive-special-folder --folder-name 'documents'",
1168
1275
  "responseShape": "single Microsoft Graph `driveItem` resource (folder)"
1169
1276
  },
1170
1277
  {
@@ -1179,7 +1286,7 @@
1179
1286
  "name": "drive-id",
1180
1287
  "key": "driveId",
1181
1288
  "required": true,
1182
- "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."
1289
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1183
1290
  },
1184
1291
  {
1185
1292
  "name": "item-id",
@@ -1206,7 +1313,7 @@
1206
1313
  }
1207
1314
  }
1208
1315
  ],
1209
- "example": "ask-marcel get-excel-chart-image --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1' --chart-id 'Chart 1' --output-path ./chart.png",
1316
+ "example": "ask-marcel-office get-excel-chart-image --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1' --chart-id 'Chart 1' --output-path ./chart.png",
1210
1317
  "responseShape": "`{ contentType: \"image/png\", size, base64 }` — the rendered chart PNG, inlined. Pair with the global `--output-path <file>` to write the PNG to disk (the response then replaces `base64` with `savedTo`).",
1211
1318
  "producesBytes": true
1212
1319
  },
@@ -1222,7 +1329,7 @@
1222
1329
  "name": "drive-id",
1223
1330
  "key": "driveId",
1224
1331
  "required": true,
1225
- "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1332
+ "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1226
1333
  },
1227
1334
  {
1228
1335
  "name": "item-id",
@@ -1234,7 +1341,7 @@
1234
1341
  "name": "worksheet-id",
1235
1342
  "key": "worksheetId",
1236
1343
  "required": true,
1237
- "description": "Worksheet ID or worksheet name. Returned by `ask-marcel list-excel-worksheets`.",
1344
+ "description": "Worksheet ID or worksheet name. Returned by `ask-marcel-office list-excel-worksheets`.",
1238
1345
  "argumentHint": {
1239
1346
  "kind": "idOrName"
1240
1347
  }
@@ -1249,7 +1356,7 @@
1249
1356
  }
1250
1357
  }
1251
1358
  ],
1252
- "example": "ask-marcel get-excel-range --drive-id 'b!1234' --item-id '01XLSX' --worksheet-id 'Sheet1' --address 'A1:C10'",
1359
+ "example": "ask-marcel-office get-excel-range --drive-id 'b!1234' --item-id '01XLSX' --worksheet-id 'Sheet1' --address 'A1:C10'",
1253
1360
  "responseShape": "single Microsoft Graph `workbookRange` resource (values, formulas, format)"
1254
1361
  },
1255
1362
  {
@@ -1264,7 +1371,7 @@
1264
1371
  "name": "drive-id",
1265
1372
  "key": "driveId",
1266
1373
  "required": true,
1267
- "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1374
+ "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1268
1375
  },
1269
1376
  {
1270
1377
  "name": "item-id",
@@ -1276,10 +1383,10 @@
1276
1383
  "name": "table-id",
1277
1384
  "key": "tableId",
1278
1385
  "required": true,
1279
- "description": "Workbook table ID or table name. Returned by `ask-marcel list-excel-tables`."
1386
+ "description": "Workbook table ID or table name. Returned by `ask-marcel-office list-excel-tables`."
1280
1387
  }
1281
1388
  ],
1282
- "example": "ask-marcel get-excel-table --drive-id 'b!1234' --item-id '01XLSX' --table-id 'Table1'",
1389
+ "example": "ask-marcel-office get-excel-table --drive-id 'b!1234' --item-id '01XLSX' --table-id 'Table1'",
1283
1390
  "responseShape": "single Microsoft Graph `workbookTable` resource"
1284
1391
  },
1285
1392
  {
@@ -1294,7 +1401,7 @@
1294
1401
  "name": "drive-id",
1295
1402
  "key": "driveId",
1296
1403
  "required": true,
1297
- "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."
1404
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
1298
1405
  },
1299
1406
  {
1300
1407
  "name": "item-id",
@@ -1306,7 +1413,7 @@
1306
1413
  "name": "worksheet-id",
1307
1414
  "key": "worksheetId",
1308
1415
  "required": true,
1309
- "description": "Accepts either the worksheet display name (e.g. `Sheet1`, `PROJECT`) or the worksheet `id` GUID returned by `list-excel-worksheets`. If neither matches Graph responds `itemNotFound: The requested resource doesn't exist.` — when that happens, double-check spelling case-sensitively against `ask-marcel list-excel-worksheets --drive-id <d> --item-id <i>`.",
1416
+ "description": "Accepts either the worksheet display name (e.g. `Sheet1`, `PROJECT`) or the worksheet `id` GUID returned by `list-excel-worksheets`. If neither matches Graph responds `itemNotFound: The requested resource doesn't exist.` — when that happens, double-check spelling case-sensitively against `ask-marcel-office list-excel-worksheets --drive-id <d> --item-id <i>`.",
1310
1417
  "argumentHint": {
1311
1418
  "kind": "idOrName"
1312
1419
  }
@@ -1324,7 +1431,7 @@
1324
1431
  "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)."
1325
1432
  }
1326
1433
  ],
1327
- "example": "ask-marcel get-excel-used-range --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1'",
1434
+ "example": "ask-marcel-office get-excel-used-range --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1'",
1328
1435
  "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`)."
1329
1436
  },
1330
1437
  {
@@ -1360,7 +1467,7 @@
1360
1467
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1361
1468
  }
1362
1469
  ],
1363
- "example": "ask-marcel get-group --group-id 'a1b2c3d4-...' --select 'id,displayName,mail'",
1470
+ "example": "ask-marcel-office get-group --group-id 'a1b2c3d4-...' --select 'id,displayName,mail'",
1364
1471
  "responseShape": "single Microsoft Graph `group` resource"
1365
1472
  },
1366
1473
  {
@@ -1375,13 +1482,13 @@
1375
1482
  "name": "message-id",
1376
1483
  "key": "messageId",
1377
1484
  "required": true,
1378
- "description": "Outlook message ID. Returned by `ask-marcel list-mail-messages`."
1485
+ "description": "Outlook message ID. Returned by `ask-marcel-office list-mail-messages`."
1379
1486
  },
1380
1487
  {
1381
1488
  "name": "attachment-id",
1382
1489
  "key": "attachmentId",
1383
1490
  "required": true,
1384
- "description": "Attachment ID. Returned by `ask-marcel list-mail-attachments`."
1491
+ "description": "Attachment ID. Returned by `ask-marcel-office list-mail-attachments`."
1385
1492
  },
1386
1493
  {
1387
1494
  "name": "select",
@@ -1396,7 +1503,7 @@
1396
1503
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1397
1504
  }
1398
1505
  ],
1399
- "example": "ask-marcel get-mail-attachment --message-id 'AAMkAGI2...' --attachment-id 'AAMkABC...'",
1506
+ "example": "ask-marcel-office get-mail-attachment --message-id 'AAMkAGI2...' --attachment-id 'AAMkABC...'",
1400
1507
  "responseShape": "single Microsoft Graph `attachment` resource. fileAttachments include `contentBytes` (Graph) AND `base64` (CLI mirror) so `--output-path` works; with `--output-path` set, both byte fields are stripped from stdout and replaced by `savedTo`. itemAttachments and referenceAttachments are returned unchanged.",
1401
1508
  "producesBytes": true
1402
1509
  },
@@ -1418,7 +1525,7 @@
1418
1525
  "key": "id"
1419
1526
  }
1420
1527
  ],
1421
- "description": "Outlook message ID. Returned by `ask-marcel list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
1528
+ "description": "Outlook message ID. Returned by `ask-marcel-office list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
1422
1529
  },
1423
1530
  {
1424
1531
  "name": "select",
@@ -1433,7 +1540,7 @@
1433
1540
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1434
1541
  }
1435
1542
  ],
1436
- "example": "ask-marcel get-mail-message --message-id 'AAMkAGI2...'",
1543
+ "example": "ask-marcel-office get-mail-message --message-id 'AAMkAGI2...'",
1437
1544
  "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."
1438
1545
  },
1439
1546
  {
@@ -1457,7 +1564,7 @@
1457
1564
  "description": "Outlook message ID. Returned by `list-mail-messages` or `search-mail-messages`. Accepts `--id` as an alias."
1458
1565
  }
1459
1566
  ],
1460
- "example": "ask-marcel get-mail-message-mime --message-id 'AAMkAD...'",
1567
+ "example": "ask-marcel-office get-mail-message-mime --message-id 'AAMkAD...'",
1461
1568
  "responseShape": "`{ contentType: \"text/plain\", size, base64 }` — Graph returns the raw MIME envelope wrapped as `text/plain` (NOT `message/rfc822` as the older docs suggested). Pair with the global `--output-path <path>` flag to land the .eml on disk and replace `base64` with `savedTo` for messages with large attachments.",
1462
1569
  "producesBytes": true
1463
1570
  },
@@ -1492,7 +1599,7 @@
1492
1599
  ]
1493
1600
  }
1494
1601
  ],
1495
- "example": "ask-marcel get-mail-rule --message-rule-id 'AQAAANC...'",
1602
+ "example": "ask-marcel-office get-mail-rule --message-rule-id 'AQAAANC...'",
1496
1603
  "responseShape": "single Microsoft Graph `messageRule` resource"
1497
1604
  },
1498
1605
  {
@@ -1503,7 +1610,7 @@
1503
1610
  "graphPathTemplate": "/me/mailboxSettings",
1504
1611
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/user-get-mailboxsettings",
1505
1612
  "options": [],
1506
- "example": "ask-marcel get-mailbox-settings",
1613
+ "example": "ask-marcel-office get-mailbox-settings",
1507
1614
  "responseShape": "single Microsoft Graph `mailboxSettings` resource"
1508
1615
  },
1509
1616
  {
@@ -1527,7 +1634,7 @@
1527
1634
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1528
1635
  }
1529
1636
  ],
1530
- "example": "ask-marcel get-my-calendar --select 'id,name'",
1637
+ "example": "ask-marcel-office get-my-calendar --select 'id,name'",
1531
1638
  "responseShape": "single Microsoft Graph `calendar` resource"
1532
1639
  },
1533
1640
  {
@@ -1551,7 +1658,7 @@
1551
1658
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1552
1659
  }
1553
1660
  ],
1554
- "example": "ask-marcel get-my-manager --select 'id,displayName,mail'",
1661
+ "example": "ask-marcel-office get-my-manager --select 'id,displayName,mail'",
1555
1662
  "responseShape": "single Microsoft Graph `user` resource on success, OR `{ manager: null, note: <string> }` when the signed-in user has no manager set. Detect the no-manager case via `data.manager === null` (also: `data.note` carries a human description)."
1556
1663
  },
1557
1664
  {
@@ -1562,7 +1669,7 @@
1562
1669
  "graphPathTemplate": "/me/photo/$value",
1563
1670
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/profilephoto-get",
1564
1671
  "options": [],
1565
- "example": "ask-marcel get-my-profile-photo",
1672
+ "example": "ask-marcel-office get-my-profile-photo",
1566
1673
  "responseShape": "`{ contentType: \"image/jpeg\", size: <bytes>, base64: \"<encoded>\" }` — the photo bytes, inlined. Pair with the global `--output-path <path>` flag to land the image on disk and replace `base64` with `savedTo`.",
1567
1674
  "producesBytes": true
1568
1675
  },
@@ -1578,7 +1685,7 @@
1578
1685
  "name": "onenote-page-id",
1579
1686
  "key": "onenotePageId",
1580
1687
  "required": true,
1581
- "description": "OneNote page ID. Returned by `ask-marcel list-onenote-section-pages`.",
1688
+ "description": "OneNote page ID. Returned by `ask-marcel-office list-onenote-section-pages`.",
1582
1689
  "aliases": [
1583
1690
  {
1584
1691
  "name": "id",
@@ -1617,7 +1724,7 @@
1617
1724
  }
1618
1725
  }
1619
1726
  ],
1620
- "example": "ask-marcel get-onenote-page-as-markdown --onenote-page-id '1-abc...'",
1727
+ "example": "ask-marcel-office get-onenote-page-as-markdown --onenote-page-id '1-abc...'",
1621
1728
  "responseShape": "`{ contentType: \"text/markdown\", size, text }` — turndown-rendered page body with inline images embedded as data URIs by default. With `--include-metadata true`, a `## OneNote metadata` block is appended after the body.",
1622
1729
  "producesBytes": true
1623
1730
  },
@@ -1633,7 +1740,7 @@
1633
1740
  "name": "onenote-page-id",
1634
1741
  "key": "onenotePageId",
1635
1742
  "required": true,
1636
- "description": "OneNote page ID. Returned by `ask-marcel list-onenote-section-pages`.",
1743
+ "description": "OneNote page ID. Returned by `ask-marcel-office list-onenote-section-pages`.",
1637
1744
  "aliases": [
1638
1745
  {
1639
1746
  "name": "id",
@@ -1646,13 +1753,13 @@
1646
1753
  ]
1647
1754
  }
1648
1755
  ],
1649
- "example": "ask-marcel get-onenote-page-content --onenote-page-id '1-abc...'",
1756
+ "example": "ask-marcel-office get-onenote-page-content --onenote-page-id '1-abc...'",
1650
1757
  "responseShape": "`{ contentType: \"text/html\", size: <chars>, text: \"<html>...\" }` — the rendered OneNote page body wrapped in a JSON envelope",
1651
1758
  "producesBytes": true
1652
1759
  },
1653
1760
  {
1654
1761
  "name": "get-organization",
1655
- "summary": "Return the tenant's organization metadata — display name, country, verified domains, business phones, technical / security notification contacts, assigned Microsoft 365 SKUs / licensing. Graph wraps the single organization resource under `value[]` (audit v1.0.0 §D7 — even though only one tenant exists, the endpoint returns a collection). The full resource is ~57 KB; use `--select` to slim it (e.g. `--select id,displayName,verifiedDomains`).",
1762
+ "summary": "Return the tenant's organization metadata — display name, country, verified domains, business phones, technical / security notification contacts, assigned Microsoft 365 SKUs / licensing. Graph wraps the single organization resource under `value[]` (— even though only one tenant exists, the endpoint returns a collection). The full resource is ~57 KB; use `--select` to slim it (e.g. `--select id,displayName,verifiedDomains`).",
1656
1763
  "category": "user",
1657
1764
  "graphMethod": "GET",
1658
1765
  "graphPathTemplate": "/organization",
@@ -1671,7 +1778,7 @@
1671
1778
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1672
1779
  }
1673
1780
  ],
1674
- "example": "ask-marcel get-organization --select 'id,displayName,verifiedDomains'",
1781
+ "example": "ask-marcel-office get-organization --select 'id,displayName,verifiedDomains'",
1675
1782
  "responseShape": "collection of one Microsoft Graph `organization` resource under `value[]`"
1676
1783
  },
1677
1784
  {
@@ -1686,7 +1793,7 @@
1686
1793
  "name": "planner-bucket-id",
1687
1794
  "key": "plannerBucketId",
1688
1795
  "required": true,
1689
- "description": "Planner bucket ID. Returned by `ask-marcel list-plan-buckets`.",
1796
+ "description": "Planner bucket ID. Returned by `ask-marcel-office list-plan-buckets`.",
1690
1797
  "aliases": [
1691
1798
  {
1692
1799
  "name": "id",
@@ -1699,7 +1806,7 @@
1699
1806
  ]
1700
1807
  }
1701
1808
  ],
1702
- "example": "ask-marcel get-planner-bucket --planner-bucket-id 'sFNeQRFu_kqhxpwwAhmA15gAGfoT'",
1809
+ "example": "ask-marcel-office get-planner-bucket --planner-bucket-id 'sFNeQRFu_kqhxpwwAhmA15gAGfoT'",
1703
1810
  "responseShape": "single Microsoft Graph `plannerBucket` resource"
1704
1811
  },
1705
1812
  {
@@ -1714,7 +1821,7 @@
1714
1821
  "name": "planner-plan-id",
1715
1822
  "key": "plannerPlanId",
1716
1823
  "required": true,
1717
- "description": "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel list-planner-tasks`.",
1824
+ "description": "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`.",
1718
1825
  "aliases": [
1719
1826
  {
1720
1827
  "name": "id",
@@ -1727,7 +1834,7 @@
1727
1834
  ]
1728
1835
  }
1729
1836
  ],
1730
- "example": "ask-marcel get-planner-plan --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
1837
+ "example": "ask-marcel-office get-planner-plan --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
1731
1838
  "responseShape": "single Microsoft Graph `plannerPlan` resource"
1732
1839
  },
1733
1840
  {
@@ -1742,7 +1849,7 @@
1742
1849
  "name": "planner-task-id",
1743
1850
  "key": "plannerTaskId",
1744
1851
  "required": true,
1745
- "description": "Planner task ID. Returned by `ask-marcel list-planner-tasks` or `list-plan-tasks`. Accepts `--task-id` as a shorter alias (each task command targets exactly one of Planner or To Do, so within this command's flag set there is no ambiguity).",
1852
+ "description": "Planner task ID. Returned by `ask-marcel-office list-planner-tasks` or `list-plan-tasks`. Accepts `--task-id` as a shorter alias (each task command targets exactly one of Planner or To Do, so within this command's flag set there is no ambiguity).",
1746
1853
  "aliases": [
1747
1854
  {
1748
1855
  "name": "id",
@@ -1755,7 +1862,7 @@
1755
1862
  ]
1756
1863
  }
1757
1864
  ],
1758
- "example": "ask-marcel get-planner-task --planner-task-id '01tx7Ic7-USXEwt0lvR1cmgAH8gK'",
1865
+ "example": "ask-marcel-office get-planner-task --planner-task-id '01tx7Ic7-USXEwt0lvR1cmgAH8gK'",
1759
1866
  "responseShape": "single Microsoft Graph `plannerTask` resource"
1760
1867
  },
1761
1868
  {
@@ -1770,7 +1877,7 @@
1770
1877
  "name": "planner-task-id",
1771
1878
  "key": "plannerTaskId",
1772
1879
  "required": true,
1773
- "description": "Planner task ID. Returned by `ask-marcel list-planner-tasks` or `list-plan-tasks`. Accepts `--task-id` as a shorter alias (each task command targets exactly one of Planner or To Do, so within this command's flag set there is no ambiguity).",
1880
+ "description": "Planner task ID. Returned by `ask-marcel-office list-planner-tasks` or `list-plan-tasks`. Accepts `--task-id` as a shorter alias (each task command targets exactly one of Planner or To Do, so within this command's flag set there is no ambiguity).",
1774
1881
  "aliases": [
1775
1882
  {
1776
1883
  "name": "id",
@@ -1783,9 +1890,64 @@
1783
1890
  ]
1784
1891
  }
1785
1892
  ],
1786
- "example": "ask-marcel get-planner-task-details --planner-task-id '01tx7Ic7-USXEwt0lvR1cmgAH8gK'",
1893
+ "example": "ask-marcel-office get-planner-task-details --planner-task-id '01tx7Ic7-USXEwt0lvR1cmgAH8gK'",
1787
1894
  "responseShape": "single Microsoft Graph `plannerTaskDetails` resource"
1788
1895
  },
1896
+ {
1897
+ "name": "get-schedule",
1898
+ "summary": "Get the free/busy availability of one or more people (or meeting rooms) over a time window — the Outlook \"scheduling assistant\" data. Pass a comma-separated list of email addresses; each result carries `availabilityView` (one character per interval: 0 free, 1 tentative, 2 busy, 3 out-of-office, 4 working-elsewhere), the underlying `scheduleItems[]` (busy blocks with start/end and, where the target's calendar permits, subject/location), and the person's `workingHours`. Read-only despite being a POST (the body is a query, nothing is created). Bounds are interpreted as UTC; per-address failures (unknown mailbox, external tenant) surface inside that entry's `error` field rather than failing the whole call.",
1899
+ "category": "calendar",
1900
+ "graphMethod": "POST",
1901
+ "graphPathTemplate": "/me/calendar/getSchedule",
1902
+ "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/calendar-getschedule",
1903
+ "options": [
1904
+ {
1905
+ "name": "schedules",
1906
+ "key": "schedules",
1907
+ "required": true,
1908
+ "aliases": [
1909
+ {
1910
+ "name": "emails",
1911
+ "key": "emails"
1912
+ }
1913
+ ],
1914
+ "description": "Comma-separated SMTP addresses of the users and/or room resources to check (e.g. `alice@contoso.com,bob@contoso.com,room-4a@contoso.com`). Resolve names to addresses first via `list-relevant-people` or `microsoft-search-query`."
1915
+ },
1916
+ {
1917
+ "name": "start-date-time",
1918
+ "key": "startDateTime",
1919
+ "required": true,
1920
+ "aliases": [
1921
+ {
1922
+ "name": "start",
1923
+ "key": "start"
1924
+ }
1925
+ ],
1926
+ "description": "Window lower bound (interpreted as UTC). 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)."
1927
+ },
1928
+ {
1929
+ "name": "end-date-time",
1930
+ "key": "endDateTime",
1931
+ "required": true,
1932
+ "aliases": [
1933
+ {
1934
+ "name": "end",
1935
+ "key": "end"
1936
+ }
1937
+ ],
1938
+ "description": "Window upper bound (interpreted as UTC). Graph caps the span at 62 days. 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)."
1939
+ },
1940
+ {
1941
+ "name": "availability-view-interval",
1942
+ "key": "availabilityViewInterval",
1943
+ "required": false,
1944
+ "description": "Slot granularity in minutes for the `availabilityView` string (5-1440; Graph defaults to 30). `15` gives quarter-hour resolution — one character per 15-minute slot."
1945
+ }
1946
+ ],
1947
+ "example": "ask-marcel-office get-schedule --schedules 'alice@contoso.com,bob@contoso.com' --start-date-time today --end-date-time +1d --availability-view-interval 30",
1948
+ "responseShape": "collection of Microsoft Graph `scheduleInformation` resources under `value[]` — one per requested address, each `{ scheduleId, availabilityView, scheduleItems: [{ status, start, end, subject?, location? }], workingHours, error? }`",
1949
+ "bodyTemplate": "{ schedules: [{schedules}], startTime: { dateTime: '{start-date-time}', timeZone: 'UTC' }, endTime: { dateTime: '{end-date-time}', timeZone: 'UTC' }, availabilityViewInterval?: {availability-view-interval} }"
1950
+ },
1789
1951
  {
1790
1952
  "name": "get-shared-mailbox-message",
1791
1953
  "summary": "Return a single message from a shared / delegated mailbox. Use `--select` to fetch only specific fields (e.g. `--select id,subject,from,receivedDateTime`) — sibling to `get-mail-message` for /me.",
@@ -1819,7 +1981,7 @@
1819
1981
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1820
1982
  }
1821
1983
  ],
1822
- "example": "ask-marcel get-shared-mailbox-message --user-id 'shared-mailbox@contoso.com' --message-id 'AAMkAD...' --select 'id,subject,from'",
1984
+ "example": "ask-marcel-office get-shared-mailbox-message --user-id 'shared-mailbox@contoso.com' --message-id 'AAMkAD...' --select 'id,subject,from'",
1823
1985
  "responseShape": "single Microsoft Graph `message` resource"
1824
1986
  },
1825
1987
  {
@@ -1864,7 +2026,7 @@
1864
2026
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1865
2027
  }
1866
2028
  ],
1867
- "example": "ask-marcel get-sharepoint-list-column --site-id '...' --list-id '...' --column-id 'Title'",
2029
+ "example": "ask-marcel-office get-sharepoint-list-column --site-id '...' --list-id '...' --column-id 'Title'",
1868
2030
  "responseShape": "single Microsoft Graph `columnDefinition` resource"
1869
2031
  },
1870
2032
  {
@@ -1885,7 +2047,7 @@
1885
2047
  "key": "id"
1886
2048
  }
1887
2049
  ],
1888
- "description": "SharePoint site ID. Either the composite ID (`hostname,site-collection-id,site-id`) returned by `ask-marcel search-sharepoint-sites-by-name`, or the literal `root` to refer to the tenant root site."
2050
+ "description": "SharePoint site ID. Either the composite ID (`hostname,site-collection-id,site-id`) returned by `ask-marcel-office search-sharepoint-sites-by-name`, or the literal `root` to refer to the tenant root site."
1889
2051
  },
1890
2052
  {
1891
2053
  "name": "select",
@@ -1900,7 +2062,7 @@
1900
2062
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1901
2063
  }
1902
2064
  ],
1903
- "example": "ask-marcel get-sharepoint-site --site-id 'contoso.sharepoint.com,1234,5678'",
2065
+ "example": "ask-marcel-office get-sharepoint-site --site-id 'contoso.sharepoint.com,1234,5678'",
1904
2066
  "responseShape": "single Microsoft Graph `site` resource"
1905
2067
  },
1906
2068
  {
@@ -1924,7 +2086,7 @@
1924
2086
  "description": "`--path` (server-relative) starts with `/`, e.g. `/sites/Marketing` or `/teams/Marketing/Subsite`. Take the URL pathname after the hostname."
1925
2087
  }
1926
2088
  ],
1927
- "example": "ask-marcel get-sharepoint-site-by-path --hostname 'contoso.sharepoint.com' --path '/sites/Marketing'",
2089
+ "example": "ask-marcel-office get-sharepoint-site-by-path --hostname 'contoso.sharepoint.com' --path '/sites/Marketing'",
1928
2090
  "responseShape": "single Microsoft Graph `site` resource"
1929
2091
  },
1930
2092
  {
@@ -1939,13 +2101,13 @@
1939
2101
  "name": "site-id",
1940
2102
  "key": "siteId",
1941
2103
  "required": true,
1942
- "description": "SharePoint site ID. Returned by `ask-marcel search-sharepoint-sites-by-name`."
2104
+ "description": "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
1943
2105
  },
1944
2106
  {
1945
2107
  "name": "drive-id",
1946
2108
  "key": "driveId",
1947
2109
  "required": true,
1948
- "description": "Drive (document library) ID on the site. Returned by `ask-marcel list-sharepoint-site-drives`."
2110
+ "description": "Drive (document library) ID on the site. Returned by `ask-marcel-office list-sharepoint-site-drives`."
1949
2111
  },
1950
2112
  {
1951
2113
  "name": "select",
@@ -1960,7 +2122,7 @@
1960
2122
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
1961
2123
  }
1962
2124
  ],
1963
- "example": "ask-marcel get-sharepoint-site-drive-by-id --site-id 'contoso.sharepoint.com,1234,5678' --drive-id 'b!abcd'",
2125
+ "example": "ask-marcel-office get-sharepoint-site-drive-by-id --site-id 'contoso.sharepoint.com,1234,5678' --drive-id 'b!abcd'",
1964
2126
  "responseShape": "single Microsoft Graph `drive` resource"
1965
2127
  },
1966
2128
  {
@@ -1975,13 +2137,13 @@
1975
2137
  "name": "site-id",
1976
2138
  "key": "siteId",
1977
2139
  "required": true,
1978
- "description": "SharePoint site ID. Returned by `ask-marcel search-sharepoint-sites-by-name`."
2140
+ "description": "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
1979
2141
  },
1980
2142
  {
1981
2143
  "name": "list-id",
1982
2144
  "key": "listId",
1983
2145
  "required": true,
1984
- "description": "SharePoint list ID or display name. Returned by `ask-marcel list-sharepoint-site-lists`.",
2146
+ "description": "SharePoint list ID or display name. Returned by `ask-marcel-office list-sharepoint-site-lists`.",
1985
2147
  "argumentHint": {
1986
2148
  "kind": "idOrName"
1987
2149
  }
@@ -1999,7 +2161,7 @@
1999
2161
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2000
2162
  }
2001
2163
  ],
2002
- "example": "ask-marcel get-sharepoint-site-list --site-id 'contoso.sharepoint.com,1234,5678' --list-id 'Documents'",
2164
+ "example": "ask-marcel-office get-sharepoint-site-list --site-id 'contoso.sharepoint.com,1234,5678' --list-id 'Documents'",
2003
2165
  "responseShape": "single Microsoft Graph `list` resource"
2004
2166
  },
2005
2167
  {
@@ -2014,13 +2176,13 @@
2014
2176
  "name": "site-id",
2015
2177
  "key": "siteId",
2016
2178
  "required": true,
2017
- "description": "SharePoint site ID. Returned by `ask-marcel search-sharepoint-sites-by-name`."
2179
+ "description": "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
2018
2180
  },
2019
2181
  {
2020
2182
  "name": "list-id",
2021
2183
  "key": "listId",
2022
2184
  "required": true,
2023
- "description": "SharePoint list ID or display name. Returned by `ask-marcel list-sharepoint-site-lists`.",
2185
+ "description": "SharePoint list ID or display name. Returned by `ask-marcel-office list-sharepoint-site-lists`.",
2024
2186
  "argumentHint": {
2025
2187
  "kind": "idOrName"
2026
2188
  }
@@ -2029,7 +2191,7 @@
2029
2191
  "name": "list-item-id",
2030
2192
  "key": "listItemId",
2031
2193
  "required": true,
2032
- "description": "listItem ID (typically a small integer). Returned by `ask-marcel list-sharepoint-site-list-items`.",
2194
+ "description": "listItem ID (typically a small integer). Returned by `ask-marcel-office list-sharepoint-site-list-items`.",
2033
2195
  "aliases": [
2034
2196
  {
2035
2197
  "name": "item-id",
@@ -2050,7 +2212,7 @@
2050
2212
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2051
2213
  }
2052
2214
  ],
2053
- "example": "ask-marcel get-sharepoint-site-list-item --site-id 'contoso.sharepoint.com,1234,5678' --list-id 'Tasks' --list-item-id '7'",
2215
+ "example": "ask-marcel-office get-sharepoint-site-list-item --site-id 'contoso.sharepoint.com,1234,5678' --list-id 'Tasks' --list-item-id '7'",
2054
2216
  "responseShape": "single Microsoft Graph `listItem` resource"
2055
2217
  },
2056
2218
  {
@@ -2080,7 +2242,7 @@
2080
2242
  ]
2081
2243
  }
2082
2244
  ],
2083
- "example": "ask-marcel get-sharepoint-site-onenote-page-content --site-id 'contoso.sharepoint.com,...' --onenote-page-id 'p1'",
2245
+ "example": "ask-marcel-office get-sharepoint-site-onenote-page-content --site-id 'contoso.sharepoint.com,...' --onenote-page-id 'p1'",
2084
2246
  "responseShape": "`{ contentType: \"text/html\", size: <chars>, text: \"<html>...\" }` — the rendered OneNote page body wrapped in a JSON envelope. Pair with the global `--output-path <path>` to write the raw HTML to disk.",
2085
2247
  "producesBytes": true
2086
2248
  },
@@ -2105,7 +2267,7 @@
2105
2267
  "description": "SharePoint site ID."
2106
2268
  }
2107
2269
  ],
2108
- "example": "ask-marcel get-site-analytics --site-id 'contoso.sharepoint.com,...'",
2270
+ "example": "ask-marcel-office get-site-analytics --site-id 'contoso.sharepoint.com,...'",
2109
2271
  "responseShape": "single Microsoft Graph `itemAnalytics` resource"
2110
2272
  },
2111
2273
  {
@@ -2120,13 +2282,13 @@
2120
2282
  "name": "calendar-id",
2121
2283
  "key": "calendarId",
2122
2284
  "required": true,
2123
- "description": "Calendar ID, or `primary` / `default` for the signed-in user's default calendar. Returned by `ask-marcel list-calendars`."
2285
+ "description": "Calendar ID, or `primary` / `default` for the signed-in user's default calendar. Returned by `ask-marcel-office list-calendars`."
2124
2286
  },
2125
2287
  {
2126
2288
  "name": "event-id",
2127
2289
  "key": "eventId",
2128
2290
  "required": true,
2129
- "description": "Event ID. Returned by `ask-marcel list-specific-calendar-events`."
2291
+ "description": "Event ID. Returned by `ask-marcel-office list-specific-calendar-events`."
2130
2292
  },
2131
2293
  {
2132
2294
  "name": "select",
@@ -2141,7 +2303,7 @@
2141
2303
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2142
2304
  }
2143
2305
  ],
2144
- "example": "ask-marcel get-specific-calendar-event --calendar-id 'primary' --event-id 'AAMkABC...' --select 'id,subject,start,end'",
2306
+ "example": "ask-marcel-office get-specific-calendar-event --calendar-id 'primary' --event-id 'AAMkABC...' --select 'id,subject,start,end'",
2145
2307
  "responseShape": "single Microsoft Graph `event` resource"
2146
2308
  },
2147
2309
  {
@@ -2162,7 +2324,7 @@
2162
2324
  "key": "id"
2163
2325
  }
2164
2326
  ],
2165
- "description": "Microsoft Teams team ID. Returned by `ask-marcel list-joined-teams`."
2327
+ "description": "Microsoft Teams team ID. Returned by `ask-marcel-office list-joined-teams`."
2166
2328
  },
2167
2329
  {
2168
2330
  "name": "select",
@@ -2177,7 +2339,7 @@
2177
2339
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2178
2340
  }
2179
2341
  ],
2180
- "example": "ask-marcel get-team --team-id 'abc-1234-...' --select displayName,description,visibility",
2342
+ "example": "ask-marcel-office get-team --team-id 'abc-1234-...' --select displayName,description,visibility",
2181
2343
  "responseShape": "single Microsoft Graph `team` resource (or projection of the requested `--select` fields)"
2182
2344
  },
2183
2345
  {
@@ -2192,13 +2354,13 @@
2192
2354
  "name": "team-id",
2193
2355
  "key": "teamId",
2194
2356
  "required": true,
2195
- "description": "Microsoft Teams team ID. Returned by `ask-marcel list-joined-teams`."
2357
+ "description": "Microsoft Teams team ID. Returned by `ask-marcel-office list-joined-teams`."
2196
2358
  },
2197
2359
  {
2198
2360
  "name": "channel-id",
2199
2361
  "key": "channelId",
2200
2362
  "required": true,
2201
- "description": "Channel ID. Returned by `ask-marcel list-team-channels`."
2363
+ "description": "Channel ID. Returned by `ask-marcel-office list-team-channels`."
2202
2364
  },
2203
2365
  {
2204
2366
  "name": "select",
@@ -2213,7 +2375,7 @@
2213
2375
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2214
2376
  }
2215
2377
  ],
2216
- "example": "ask-marcel get-team-channel --team-id 'abc-1234-...' --channel-id '19:def@thread.tacv2' --select 'id,displayName'",
2378
+ "example": "ask-marcel-office get-team-channel --team-id 'abc-1234-...' --channel-id '19:def@thread.tacv2' --select 'id,displayName'",
2217
2379
  "responseShape": "single Microsoft Graph `channel` resource"
2218
2380
  },
2219
2381
  {
@@ -2249,7 +2411,7 @@
2249
2411
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2250
2412
  }
2251
2413
  ],
2252
- "example": "ask-marcel get-team-primary-channel --team-id 'tm1'",
2414
+ "example": "ask-marcel-office get-team-primary-channel --team-id 'tm1'",
2253
2415
  "responseShape": "single Microsoft Graph `channel` resource"
2254
2416
  },
2255
2417
  {
@@ -2273,7 +2435,7 @@
2273
2435
  "description": "Teams chat message ID. Source via `list-teams-chats-with-messages` or `list-teams-chat-messages`."
2274
2436
  }
2275
2437
  ],
2276
- "example": "ask-marcel get-teams-chat-message --chat-id '19:abc...@unq.gbl.spaces' --message-id '1700000000000'",
2438
+ "example": "ask-marcel-office get-teams-chat-message --chat-id '19:abc...@unq.gbl.spaces' --message-id '1700000000000'",
2277
2439
  "responseShape": "single Teams chat message — `id`, `from`, `imDisplayName`, `content`, `contentType`, `composeTime`, `originalArrivalTime`, etc. **Microsoft-internal schema — fields may change without notice.**",
2278
2440
  "needsSubstrateToken": true,
2279
2441
  "stability": "experimental"
@@ -2290,7 +2452,7 @@
2290
2452
  "name": "todo-task-list-id",
2291
2453
  "key": "todoTaskListId",
2292
2454
  "required": true,
2293
- "description": "To Do task list ID. Returned by `ask-marcel list-todo-task-lists`.",
2455
+ "description": "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`.",
2294
2456
  "aliases": [
2295
2457
  {
2296
2458
  "name": "task-list-id",
@@ -2306,7 +2468,7 @@
2306
2468
  "name": "todo-task-id",
2307
2469
  "key": "todoTaskId",
2308
2470
  "required": true,
2309
- "description": "To Do task ID. Returned by `ask-marcel list-todo-tasks`. Accepts `--task-id` as a shorter alias (within this command's flag set the To Do context is unambiguous).",
2471
+ "description": "To Do task ID. Returned by `ask-marcel-office list-todo-tasks`. Accepts `--task-id` as a shorter alias (within this command's flag set the To Do context is unambiguous).",
2310
2472
  "aliases": [
2311
2473
  {
2312
2474
  "name": "task-id",
@@ -2327,7 +2489,7 @@
2327
2489
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2328
2490
  }
2329
2491
  ],
2330
- "example": "ask-marcel get-todo-task --todo-task-list-id 'AAMkAGI...' --todo-task-id 'AAMkABC...'",
2492
+ "example": "ask-marcel-office get-todo-task --todo-task-list-id 'AAMkAGI...' --todo-task-id 'AAMkABC...'",
2331
2493
  "responseShape": "single Microsoft Graph `todoTask` resource (slimmed by `--select` when supplied)"
2332
2494
  },
2333
2495
  {
@@ -2363,7 +2525,7 @@
2363
2525
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2364
2526
  }
2365
2527
  ],
2366
- "example": "ask-marcel get-user-manager --user-id 'alice@contoso.com' --select 'id,displayName,mail'",
2528
+ "example": "ask-marcel-office get-user-manager --user-id 'alice@contoso.com' --select 'id,displayName,mail'",
2367
2529
  "responseShape": "single Microsoft Graph `user` resource on success, OR `{ manager: null, note: <string> }` when the target user has no manager set. Detect the no-manager case via `data.manager === null` (same discriminator as `get-my-manager`)."
2368
2530
  },
2369
2531
  {
@@ -2393,7 +2555,7 @@
2393
2555
  "description": "Pass `--count-files true` to add `estimatedFileCount` to each drive — the Microsoft Search index's security-trimmed `driveItem` total (files + folders) scoped to that drive's `webUrl` via KQL `path:`. OFF by default because it issues ONE extra Search query per drive (chunked, capped at 200) — a real fan-out with 429-throttling risk on large drive sets. It is an estimate, not an exact count."
2394
2556
  }
2395
2557
  ],
2396
- "example": "ask-marcel list-accessible-drives --output json",
2558
+ "example": "ask-marcel-office list-accessible-drives --output json",
2397
2559
  "responseShape": "`{ value: [{ id, name, driveType, webUrl, sources: [\"activity\"|\"channel\"|\"joinedTeam\"|\"memberOfGroup\"|\"personal\"|\"sharedWithMe\"|\"siteLibrary\"], groupId?, size?, estimatedFileCount? }], count, fileEstimate?, truncated?: true, partialErrors?: [{ source, error }] }`. `estimatedFileCount` appears only with `--count-files true` — the security-trimmed `driveItem` (files+folders) estimate scoped to each drive, omitted past the 200-drive count cap or when the per-drive query fails. `value[]` is deduped by drive `id` and sorted by id; `sources[]` lists every vector that surfaced the drive (`channel` = a private/shared Teams channel files folder; `activity` = a recently-used / followed / trending item drive; `siteLibrary` = a non-default document library of a discovered site); `groupId` is present only for Teams/group drives. `size` (when present) is the drive's total bytes used (`quota.used`, recursive) — surfaced free from the drive resource, omitted for the rare drive without a quota facet; it is a data-volume signal, not a file count. `fileEstimate` (best-effort, omitted if the extra query fails) is the Microsoft Search index's security-trimmed `driveItem` count — roughly how many files+folders you can access across ALL of SharePoint/OneDrive; it is INDEX-WIDE, not limited to the `value[]` drives above. `truncated: true` means a `--max-groups` cap was hit — raise it to see more. `partialErrors[]` (present only when something actionable failed) names each vector/group/channel/site whose sub-call returned an actionable error (auth, throttling, 5xx, network); benign \"can't reach this one\" results (404/403/423/400) are dropped, not listed."
2398
2560
  },
2399
2561
  {
@@ -2441,7 +2603,7 @@
2441
2603
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2442
2604
  }
2443
2605
  ],
2444
- "example": "ask-marcel list-all-onenote-sections",
2606
+ "example": "ask-marcel-office list-all-onenote-sections",
2445
2607
  "responseShape": "collection of Microsoft Graph `onenoteSection` resources under `value[]`",
2446
2608
  "pagination": true
2447
2609
  },
@@ -2463,7 +2625,7 @@
2463
2625
  "key": "id"
2464
2626
  }
2465
2627
  ],
2466
- "description": "Outlook calendar event ID. Returned by `ask-marcel list-calendar-events` or `get-calendar-event`."
2628
+ "description": "Outlook calendar event ID. Returned by `ask-marcel-office list-calendar-events` or `get-calendar-event`."
2467
2629
  },
2468
2630
  {
2469
2631
  "name": "top",
@@ -2502,7 +2664,7 @@
2502
2664
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2503
2665
  }
2504
2666
  ],
2505
- "example": "ask-marcel list-calendar-event-attachments --event-id 'AAMkAGI2...'",
2667
+ "example": "ask-marcel-office list-calendar-event-attachments --event-id 'AAMkAGI2...'",
2506
2668
  "responseShape": "collection of Microsoft Graph `attachment` resources under `value[]` (slim metadata by default — see summary). Graph always includes `@odata.type` and `@odata.mediaContentType` on every entry regardless of `--select` — that discriminator is what the attachment-converting commands branch on.",
2507
2669
  "pagination": true
2508
2670
  },
@@ -2518,7 +2680,7 @@
2518
2680
  "name": "calendar-id",
2519
2681
  "key": "calendarId",
2520
2682
  "required": false,
2521
- "description": "Calendar ID, or `primary` / `default` for the signed-in user’s default calendar. Optional; defaults to `primary`. Returned by `ask-marcel list-calendars`.",
2683
+ "description": "Calendar ID, or `primary` / `default` for the signed-in user’s default calendar. Optional; defaults to `primary`. Returned by `ask-marcel-office list-calendars`.",
2522
2684
  "argumentHint": {
2523
2685
  "kind": "magicValue",
2524
2686
  "values": [
@@ -2537,7 +2699,7 @@
2537
2699
  "key": "id"
2538
2700
  }
2539
2701
  ],
2540
- "description": "Recurring event ID. Returned by `ask-marcel list-specific-calendar-events`."
2702
+ "description": "Recurring event ID. Returned by `ask-marcel-office list-specific-calendar-events`."
2541
2703
  },
2542
2704
  {
2543
2705
  "name": "start-date-time",
@@ -2600,7 +2762,7 @@
2600
2762
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2601
2763
  }
2602
2764
  ],
2603
- "example": "ask-marcel list-calendar-event-instances --calendar-id 'AAMkAGI2THVS...' --event-id 'AAMkABC...' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
2765
+ "example": "ask-marcel-office list-calendar-event-instances --calendar-id 'AAMkAGI2THVS...' --event-id 'AAMkABC...' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
2604
2766
  "responseShape": "collection of Microsoft Graph `event` resources (single occurrences) under `value[]`",
2605
2767
  "pagination": true
2606
2768
  },
@@ -2649,7 +2811,7 @@
2649
2811
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2650
2812
  }
2651
2813
  ],
2652
- "example": "ask-marcel list-calendar-events",
2814
+ "example": "ask-marcel-office list-calendar-events",
2653
2815
  "responseShape": "collection of Microsoft Graph `event` resources under `value[]`",
2654
2816
  "pagination": true
2655
2817
  },
@@ -2668,7 +2830,7 @@
2668
2830
  "description": "OData $top: maximum number of items to return on this page (positive integer, ≤ 1000). Graph silently caps at 1000 on every collection endpoint, so the CLI rejects larger values with a clear validation error rather than letting the request silently truncate. Combine with `next-page` to paginate beyond the cap."
2669
2831
  }
2670
2832
  ],
2671
- "example": "ask-marcel list-calendar-events-delta --top 50",
2833
+ "example": "ask-marcel-office list-calendar-events-delta --top 50",
2672
2834
  "responseShape": "collection of changed Microsoft Graph `event` resources under `data.value[]`. Cursor tokens are hoisted to envelope level: top-level `nextLink` while paging, then top-level `deltaLink` on the final page.",
2673
2835
  "pagination": true
2674
2836
  },
@@ -2729,7 +2891,7 @@
2729
2891
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2730
2892
  }
2731
2893
  ],
2732
- "example": "ask-marcel list-calendar-group-calendars --calendar-group-id 'AAMkADk0...'",
2894
+ "example": "ask-marcel-office list-calendar-group-calendars --calendar-group-id 'AAMkADk0...'",
2733
2895
  "responseShape": "collection of Microsoft Graph `calendar` resources under `value[]`",
2734
2896
  "pagination": true
2735
2897
  },
@@ -2778,7 +2940,7 @@
2778
2940
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2779
2941
  }
2780
2942
  ],
2781
- "example": "ask-marcel list-calendar-groups",
2943
+ "example": "ask-marcel-office list-calendar-groups",
2782
2944
  "responseShape": "collection of Microsoft Graph `calendarGroup` resources under `value[]`",
2783
2945
  "pagination": true
2784
2946
  },
@@ -2851,7 +3013,7 @@
2851
3013
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2852
3014
  }
2853
3015
  ],
2854
- "example": "ask-marcel list-calendar-view --start-date-time 'start-of-week' --end-date-time 'end-of-week'",
3016
+ "example": "ask-marcel-office list-calendar-view --start-date-time 'start-of-week' --end-date-time 'end-of-week'",
2855
3017
  "responseShape": "collection of Microsoft Graph `event` resources (single occurrences) under `value[]`"
2856
3018
  },
2857
3019
  {
@@ -2893,7 +3055,7 @@
2893
3055
  "description": "OData $top: maximum number of items to return on this page (positive integer, ≤ 1000). Graph silently caps at 1000 on every collection endpoint, so the CLI rejects larger values with a clear validation error rather than letting the request silently truncate. Combine with `next-page` to paginate beyond the cap."
2894
3056
  }
2895
3057
  ],
2896
- "example": "ask-marcel list-calendar-view-delta --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z' --top 50",
3058
+ "example": "ask-marcel-office list-calendar-view-delta --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z' --top 50",
2897
3059
  "responseShape": "collection of changed Microsoft Graph `event` occurrences under `data.value[]`. Cursor tokens are hoisted to envelope level: top-level `nextLink` while paging, then top-level `deltaLink` on the final page.",
2898
3060
  "pagination": true
2899
3061
  },
@@ -2942,7 +3104,7 @@
2942
3104
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
2943
3105
  }
2944
3106
  ],
2945
- "example": "ask-marcel list-calendars",
3107
+ "example": "ask-marcel-office list-calendars",
2946
3108
  "responseShape": "collection of Microsoft Graph `calendar` resources under `value[]`",
2947
3109
  "pagination": true
2948
3110
  },
@@ -2964,7 +3126,7 @@
2964
3126
  "key": "id"
2965
3127
  }
2966
3128
  ],
2967
- "description": "Microsoft Teams chat ID, e.g. `19:abc...@thread.v2`. Source the ID via `ask-marcel list-chats` (returns chat metadata for the signed-in user). Alternative sources outside the CLI: the Teams desktop / web client (Open in browser → URL contains the chat thread ID), Microsoft Graph Explorer, or URL-decode the `19%3ameeting_...%40thread.v2` segment of an `onlineMeeting.joinUrl` from `list-calendar-events`."
3129
+ "description": "Microsoft Teams chat ID, e.g. `19:abc...@thread.v2`. Source the ID via `ask-marcel-office list-chats` (returns chat metadata for the signed-in user). Alternative sources outside the CLI: the Teams desktop / web client (Open in browser → URL contains the chat thread ID), Microsoft Graph Explorer, or URL-decode the `19%3ameeting_...%40thread.v2` segment of an `onlineMeeting.joinUrl` from `list-calendar-events`."
2968
3130
  },
2969
3131
  {
2970
3132
  "name": "skip",
@@ -2985,7 +3147,7 @@
2985
3147
  "description": "OData $filter: predicate to narrow results server-side. Quoting rules: string literals MUST use SINGLE quotes (`subject eq 'invoice'`), NOT double quotes — Graph rejects `subject eq \"invoice\"` with `InvalidFilterClause`. To embed a single quote inside a string, double it (`subject eq 'O''Brien'`). Booleans, numbers, and dates are unquoted (`isRead eq false`, `receivedDateTime ge 2026-01-01T00:00:00Z`). Wrap the whole flag value in shell DOUBLE quotes so the inner single quotes survive (`--filter \"subject eq 'invoice'\"`). Same syntax Graph documents per resource type."
2986
3148
  }
2987
3149
  ],
2988
- "example": "ask-marcel list-chat-members --chat-id '19:abc...@thread.v2'",
3150
+ "example": "ask-marcel-office list-chat-members --chat-id '19:abc...@thread.v2'",
2989
3151
  "responseShape": "collection of Microsoft Graph `conversationMember` resources under `value[]`",
2990
3152
  "pagination": true
2991
3153
  },
@@ -3022,7 +3184,7 @@
3022
3184
  "description": "OData $filter: predicate to narrow results server-side. Quoting rules: string literals MUST use SINGLE quotes (`subject eq 'invoice'`), NOT double quotes — Graph rejects `subject eq \"invoice\"` with `InvalidFilterClause`. To embed a single quote inside a string, double it (`subject eq 'O''Brien'`). Booleans, numbers, and dates are unquoted (`isRead eq false`, `receivedDateTime ge 2026-01-01T00:00:00Z`). Wrap the whole flag value in shell DOUBLE quotes so the inner single quotes survive (`--filter \"subject eq 'invoice'\"`). Same syntax Graph documents per resource type."
3023
3185
  }
3024
3186
  ],
3025
- "example": "ask-marcel list-chats",
3187
+ "example": "ask-marcel-office list-chats",
3026
3188
  "responseShape": "collection of Microsoft Graph `chat` resources under `value[]`, each projected to the default `--select` set (or, when overridden, to the requested fields).",
3027
3189
  "pagination": true,
3028
3190
  "needsElevatedToken": true
@@ -3072,7 +3234,7 @@
3072
3234
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3073
3235
  }
3074
3236
  ],
3075
- "example": "ask-marcel list-conversation-messages --conversation-id 'AAQkAD...=' --top 5 --select id,subject,receivedDateTime",
3237
+ "example": "ask-marcel-office list-conversation-messages --conversation-id 'AAQkAD...=' --top 5 --select id,subject,receivedDateTime",
3076
3238
  "responseShape": "collection of Microsoft Graph `message` resources under `value[]` (unordered)",
3077
3239
  "pagination": true
3078
3240
  },
@@ -3088,7 +3250,7 @@
3088
3250
  "name": "drive-id",
3089
3251
  "key": "driveId",
3090
3252
  "required": true,
3091
- "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."
3253
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3092
3254
  },
3093
3255
  {
3094
3256
  "name": "item-id",
@@ -3127,7 +3289,7 @@
3127
3289
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3128
3290
  }
3129
3291
  ],
3130
- "example": "ask-marcel list-drive-item-permissions --drive-id 'b!1234' --item-id '01ABC'",
3292
+ "example": "ask-marcel-office list-drive-item-permissions --drive-id 'b!1234' --item-id '01ABC'",
3131
3293
  "responseShape": "collection of Microsoft Graph `permission` resources under `value[]`",
3132
3294
  "pagination": true
3133
3295
  },
@@ -3143,7 +3305,7 @@
3143
3305
  "name": "drive-id",
3144
3306
  "key": "driveId",
3145
3307
  "required": true,
3146
- "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."
3308
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3147
3309
  },
3148
3310
  {
3149
3311
  "name": "item-id",
@@ -3182,7 +3344,7 @@
3182
3344
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3183
3345
  }
3184
3346
  ],
3185
- "example": "ask-marcel list-drive-item-thumbnails --drive-id 'b!1234' --item-id '01ABC'",
3347
+ "example": "ask-marcel-office list-drive-item-thumbnails --drive-id 'b!1234' --item-id '01ABC'",
3186
3348
  "responseShape": "collection of Microsoft Graph `thumbnailSet` resources under `value[]`",
3187
3349
  "pagination": true
3188
3350
  },
@@ -3198,7 +3360,7 @@
3198
3360
  "name": "drive-id",
3199
3361
  "key": "driveId",
3200
3362
  "required": true,
3201
- "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."
3363
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3202
3364
  },
3203
3365
  {
3204
3366
  "name": "item-id",
@@ -3237,7 +3399,7 @@
3237
3399
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3238
3400
  }
3239
3401
  ],
3240
- "example": "ask-marcel list-drive-item-versions --drive-id 'b!1234' --item-id '01ABC'",
3402
+ "example": "ask-marcel-office list-drive-item-versions --drive-id 'b!1234' --item-id '01ABC'",
3241
3403
  "responseShape": "collection of Microsoft Graph `driveItemVersion` resources under `value[]`",
3242
3404
  "pagination": true
3243
3405
  },
@@ -3286,7 +3448,7 @@
3286
3448
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3287
3449
  }
3288
3450
  ],
3289
- "example": "ask-marcel list-drives",
3451
+ "example": "ask-marcel-office list-drives",
3290
3452
  "responseShape": "collection of Microsoft Graph `drive` resources under `value[]`",
3291
3453
  "pagination": true
3292
3454
  },
@@ -3302,7 +3464,7 @@
3302
3464
  "name": "drive-id",
3303
3465
  "key": "driveId",
3304
3466
  "required": true,
3305
- "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."
3467
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3306
3468
  },
3307
3469
  {
3308
3470
  "name": "item-id",
@@ -3347,7 +3509,7 @@
3347
3509
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3348
3510
  }
3349
3511
  ],
3350
- "example": "ask-marcel list-excel-comments --drive-id 'b!1234' --item-id '01ABC'",
3512
+ "example": "ask-marcel-office list-excel-comments --drive-id 'b!1234' --item-id '01ABC'",
3351
3513
  "responseShape": "collection of Microsoft Graph `workbookComment` resources under `value[]`",
3352
3514
  "pagination": true
3353
3515
  },
@@ -3363,7 +3525,7 @@
3363
3525
  "name": "drive-id",
3364
3526
  "key": "driveId",
3365
3527
  "required": true,
3366
- "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."
3528
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3367
3529
  },
3368
3530
  {
3369
3531
  "name": "item-id",
@@ -3408,7 +3570,7 @@
3408
3570
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3409
3571
  }
3410
3572
  ],
3411
- "example": "ask-marcel list-excel-defined-names --drive-id 'b!1234' --item-id '01ABC'",
3573
+ "example": "ask-marcel-office list-excel-defined-names --drive-id 'b!1234' --item-id '01ABC'",
3412
3574
  "responseShape": "collection of Microsoft Graph `workbookNamedItem` resources under `value[]`",
3413
3575
  "pagination": true
3414
3576
  },
@@ -3424,7 +3586,7 @@
3424
3586
  "name": "drive-id",
3425
3587
  "key": "driveId",
3426
3588
  "required": true,
3427
- "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3589
+ "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3428
3590
  },
3429
3591
  {
3430
3592
  "name": "item-id",
@@ -3436,7 +3598,7 @@
3436
3598
  "name": "table-id",
3437
3599
  "key": "tableId",
3438
3600
  "required": true,
3439
- "description": "Workbook table ID or table name. Returned by `ask-marcel list-excel-tables`."
3601
+ "description": "Workbook table ID or table name. Returned by `ask-marcel-office list-excel-tables`."
3440
3602
  },
3441
3603
  {
3442
3604
  "name": "top",
@@ -3463,7 +3625,7 @@
3463
3625
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3464
3626
  }
3465
3627
  ],
3466
- "example": "ask-marcel list-excel-table-rows --drive-id 'b!1234' --item-id '01XLSX' --table-id 'Table1'",
3628
+ "example": "ask-marcel-office list-excel-table-rows --drive-id 'b!1234' --item-id '01XLSX' --table-id 'Table1'",
3467
3629
  "responseShape": "collection of Microsoft Graph `workbookTableRow` resources (each `values` is a 2D array) under `value[]`",
3468
3630
  "pagination": true
3469
3631
  },
@@ -3479,7 +3641,7 @@
3479
3641
  "name": "drive-id",
3480
3642
  "key": "driveId",
3481
3643
  "required": true,
3482
- "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3644
+ "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3483
3645
  },
3484
3646
  {
3485
3647
  "name": "item-id",
@@ -3512,7 +3674,7 @@
3512
3674
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3513
3675
  }
3514
3676
  ],
3515
- "example": "ask-marcel list-excel-tables --drive-id 'b!1234' --item-id '01XLSX'",
3677
+ "example": "ask-marcel-office list-excel-tables --drive-id 'b!1234' --item-id '01XLSX'",
3516
3678
  "responseShape": "collection of Microsoft Graph `workbookTable` resources under `value[]`",
3517
3679
  "pagination": true
3518
3680
  },
@@ -3528,7 +3690,7 @@
3528
3690
  "name": "drive-id",
3529
3691
  "key": "driveId",
3530
3692
  "required": true,
3531
- "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."
3693
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3532
3694
  },
3533
3695
  {
3534
3696
  "name": "item-id",
@@ -3582,7 +3744,7 @@
3582
3744
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3583
3745
  }
3584
3746
  ],
3585
- "example": "ask-marcel list-excel-worksheet-charts --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1'",
3747
+ "example": "ask-marcel-office list-excel-worksheet-charts --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1'",
3586
3748
  "responseShape": "collection of Microsoft Graph `workbookChart` resources under `value[]`",
3587
3749
  "pagination": true
3588
3750
  },
@@ -3598,7 +3760,7 @@
3598
3760
  "name": "drive-id",
3599
3761
  "key": "driveId",
3600
3762
  "required": true,
3601
- "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."
3763
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3602
3764
  },
3603
3765
  {
3604
3766
  "name": "item-id",
@@ -3652,7 +3814,7 @@
3652
3814
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3653
3815
  }
3654
3816
  ],
3655
- "example": "ask-marcel list-excel-worksheet-pivot-tables --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1'",
3817
+ "example": "ask-marcel-office list-excel-worksheet-pivot-tables --drive-id 'b!1234' --item-id '01ABC' --worksheet-id 'Sheet1'",
3656
3818
  "responseShape": "collection of Microsoft Graph `workbookPivotTable` resources under `value[]`",
3657
3819
  "pagination": true
3658
3820
  },
@@ -3668,7 +3830,7 @@
3668
3830
  "name": "drive-id",
3669
3831
  "key": "driveId",
3670
3832
  "required": true,
3671
- "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3833
+ "description": "Microsoft Graph drive ID containing the workbook. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3672
3834
  },
3673
3835
  {
3674
3836
  "name": "item-id",
@@ -3695,7 +3857,7 @@
3695
3857
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3696
3858
  }
3697
3859
  ],
3698
- "example": "ask-marcel list-excel-worksheets --drive-id 'b!1234' --item-id '01XLSX'",
3860
+ "example": "ask-marcel-office list-excel-worksheets --drive-id 'b!1234' --item-id '01XLSX'",
3699
3861
  "responseShape": "collection of Microsoft Graph `worksheet` resources under `value[]`",
3700
3862
  "pagination": true
3701
3863
  },
@@ -3744,7 +3906,7 @@
3744
3906
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3745
3907
  }
3746
3908
  ],
3747
- "example": "ask-marcel list-focused-inbox-overrides",
3909
+ "example": "ask-marcel-office list-focused-inbox-overrides",
3748
3910
  "responseShape": "collection of Microsoft Graph `inferenceClassificationOverride` resources under `value[]`",
3749
3911
  "pagination": true
3750
3912
  },
@@ -3760,13 +3922,13 @@
3760
3922
  "name": "drive-id",
3761
3923
  "key": "driveId",
3762
3924
  "required": true,
3763
- "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."
3925
+ "description": "Microsoft Graph drive ID. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
3764
3926
  },
3765
3927
  {
3766
3928
  "name": "item-id",
3767
3929
  "key": "itemId",
3768
3930
  "required": true,
3769
- "description": "driveItem ID of the folder (Graph identifies folders as driveItems too — there is no separate folder type). Use the root folder ID from `ask-marcel get-drive-root-item` to list the top of a drive. Accepts `--folder-id` as an alias since the command name implies \"folder\".",
3931
+ "description": "driveItem ID of the folder (Graph identifies folders as driveItems too — there is no separate folder type). Use the root folder ID from `ask-marcel-office get-drive-root-item` to list the top of a drive. Accepts `--folder-id` as an alias since the command name implies \"folder\".",
3770
3932
  "aliases": [
3771
3933
  {
3772
3934
  "name": "folder-id",
@@ -3805,7 +3967,7 @@
3805
3967
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3806
3968
  }
3807
3969
  ],
3808
- "example": "ask-marcel list-folder-files --drive-id 'b!1234' --item-id '01ROOT'",
3970
+ "example": "ask-marcel-office list-folder-files --drive-id 'b!1234' --item-id '01ROOT'",
3809
3971
  "responseShape": "collection of Microsoft Graph `driveItem` resources under `value[]`",
3810
3972
  "pagination": true
3811
3973
  },
@@ -3848,7 +4010,7 @@
3848
4010
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3849
4011
  }
3850
4012
  ],
3851
- "example": "ask-marcel list-followed-drive-items",
4013
+ "example": "ask-marcel-office list-followed-drive-items",
3852
4014
  "responseShape": "collection of Microsoft Graph `driveItem` resources under `value[]`",
3853
4015
  "pagination": true
3854
4016
  },
@@ -3933,7 +4095,7 @@
3933
4095
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3934
4096
  }
3935
4097
  ],
3936
- "example": "ask-marcel list-group-calendar-view --group-id 'a1b2c3d4-...' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
4098
+ "example": "ask-marcel-office list-group-calendar-view --group-id 'a1b2c3d4-...' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
3937
4099
  "responseShape": "collection of Microsoft Graph `event` resources under `value[]`",
3938
4100
  "pagination": true
3939
4101
  },
@@ -3994,7 +4156,7 @@
3994
4156
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
3995
4157
  }
3996
4158
  ],
3997
- "example": "ask-marcel list-group-conversations --group-id 'a1b2c3d4-...'",
4159
+ "example": "ask-marcel-office list-group-conversations --group-id 'a1b2c3d4-...'",
3998
4160
  "responseShape": "collection of Microsoft Graph `conversation` resources under `value[]`",
3999
4161
  "pagination": true
4000
4162
  },
@@ -4055,7 +4217,7 @@
4055
4217
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4056
4218
  }
4057
4219
  ],
4058
- "example": "ask-marcel list-group-events --group-id 'a1b2c3d4-...'",
4220
+ "example": "ask-marcel-office list-group-events --group-id 'a1b2c3d4-...'",
4059
4221
  "responseShape": "collection of Microsoft Graph `event` resources under `value[]`",
4060
4222
  "pagination": true
4061
4223
  },
@@ -4116,7 +4278,7 @@
4116
4278
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4117
4279
  }
4118
4280
  ],
4119
- "example": "ask-marcel list-group-members --group-id 'a1b2c3d4-...'",
4281
+ "example": "ask-marcel-office list-group-members --group-id 'a1b2c3d4-...'",
4120
4282
  "responseShape": "collection of Microsoft Graph `directoryObject` resources under `value[]`",
4121
4283
  "pagination": true
4122
4284
  },
@@ -4177,7 +4339,7 @@
4177
4339
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4178
4340
  }
4179
4341
  ],
4180
- "example": "ask-marcel list-group-owners --group-id 'a1b2c3d4-...'",
4342
+ "example": "ask-marcel-office list-group-owners --group-id 'a1b2c3d4-...'",
4181
4343
  "responseShape": "collection of Microsoft Graph `directoryObject` resources under `value[]`",
4182
4344
  "pagination": true
4183
4345
  },
@@ -4238,7 +4400,7 @@
4238
4400
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4239
4401
  }
4240
4402
  ],
4241
- "example": "ask-marcel list-group-threads --group-id 'a1b2c3d4-...'",
4403
+ "example": "ask-marcel-office list-group-threads --group-id 'a1b2c3d4-...'",
4242
4404
  "responseShape": "collection of Microsoft Graph `conversationThread` resources under `value[]`",
4243
4405
  "pagination": true
4244
4406
  },
@@ -4281,7 +4443,7 @@
4281
4443
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4282
4444
  }
4283
4445
  ],
4284
- "example": "ask-marcel list-groups",
4446
+ "example": "ask-marcel-office list-groups",
4285
4447
  "responseShape": "collection of Microsoft Graph `group` resources under `value[]`",
4286
4448
  "pagination": true
4287
4449
  },
@@ -4330,7 +4492,7 @@
4330
4492
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4331
4493
  }
4332
4494
  ],
4333
- "example": "ask-marcel list-incomplete-planner-tasks --top 25",
4495
+ "example": "ask-marcel-office list-incomplete-planner-tasks --top 25",
4334
4496
  "responseShape": "collection of Microsoft Graph `plannerTask` resources under `value[]` where `percentComplete < 100`",
4335
4497
  "pagination": true
4336
4498
  },
@@ -4346,7 +4508,7 @@
4346
4508
  "name": "todo-task-list-id",
4347
4509
  "key": "todoTaskListId",
4348
4510
  "required": true,
4349
- "description": "todoTaskList ID. Returned by `ask-marcel list-todo-task-lists`. The well-known name `tasks` (the default list) is accepted on this incomplete-tasks endpoint specifically — sibling commands like `list-todo-tasks` and `list-todo-tasks-delta` only accept resolved IDs. There is no Graph endpoint that returns incomplete tasks across every list — call this once per list.",
4511
+ "description": "todoTaskList ID. Returned by `ask-marcel-office list-todo-task-lists`. The well-known name `tasks` (the default list) is accepted on this incomplete-tasks endpoint specifically — sibling commands like `list-todo-tasks` and `list-todo-tasks-delta` only accept resolved IDs. There is no Graph endpoint that returns incomplete tasks across every list — call this once per list.",
4350
4512
  "aliases": [
4351
4513
  {
4352
4514
  "name": "id",
@@ -4399,7 +4561,7 @@
4399
4561
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4400
4562
  }
4401
4563
  ],
4402
- "example": "ask-marcel list-incomplete-todo-tasks --todo-task-list-id 'tasks' --top 5",
4564
+ "example": "ask-marcel-office list-incomplete-todo-tasks --todo-task-list-id 'tasks' --top 5",
4403
4565
  "responseShape": "collection of Microsoft Graph `todoTask` resources under `value[]` where `status != \"completed\"`",
4404
4566
  "pagination": true
4405
4567
  },
@@ -4411,7 +4573,7 @@
4411
4573
  "graphPathTemplate": "/me/joinedTeams",
4412
4574
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/user-list-joinedteams",
4413
4575
  "options": [],
4414
- "example": "ask-marcel list-joined-teams",
4576
+ "example": "ask-marcel-office list-joined-teams",
4415
4577
  "responseShape": "collection of Microsoft Graph `team` resources under `value[]`",
4416
4578
  "pagination": true
4417
4579
  },
@@ -4433,7 +4595,7 @@
4433
4595
  "key": "id"
4434
4596
  }
4435
4597
  ],
4436
- "description": "Outlook message ID. Returned by `ask-marcel list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
4598
+ "description": "Outlook message ID. Returned by `ask-marcel-office list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
4437
4599
  },
4438
4600
  {
4439
4601
  "name": "top",
@@ -4472,7 +4634,7 @@
4472
4634
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4473
4635
  }
4474
4636
  ],
4475
- "example": "ask-marcel list-mail-attachments --message-id 'AAMkAGI2...'",
4637
+ "example": "ask-marcel-office list-mail-attachments --message-id 'AAMkAGI2...'",
4476
4638
  "responseShape": "collection of Microsoft Graph `attachment` resources under `value[]` (slim metadata by default — see summary). Graph always includes `@odata.type` and `@odata.mediaContentType` on every entry regardless of `--select` — these fields are the discriminator the attachment-converting commands branch on; don't be surprised to see them appear even if you didn't request them.",
4477
4639
  "pagination": true
4478
4640
  },
@@ -4494,7 +4656,7 @@
4494
4656
  "key": "id"
4495
4657
  }
4496
4658
  ],
4497
- "description": "mailFolder ID. Returned by `ask-marcel list-mail-folders`. Well-known names also work, e.g. `inbox`, `sentitems`, `drafts`."
4659
+ "description": "mailFolder ID. Returned by `ask-marcel-office list-mail-folders`. Well-known names also work, e.g. `inbox`, `sentitems`, `drafts`."
4498
4660
  },
4499
4661
  {
4500
4662
  "name": "top",
@@ -4533,7 +4695,7 @@
4533
4695
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4534
4696
  }
4535
4697
  ],
4536
- "example": "ask-marcel list-mail-child-folders --mail-folder-id 'inbox'",
4698
+ "example": "ask-marcel-office list-mail-child-folders --mail-folder-id 'inbox'",
4537
4699
  "responseShape": "collection of Microsoft Graph `mailFolder` resources under `value[]`",
4538
4700
  "pagination": true
4539
4701
  },
@@ -4555,7 +4717,7 @@
4555
4717
  "key": "id"
4556
4718
  }
4557
4719
  ],
4558
- "description": "mailFolder ID. Returned by `ask-marcel list-mail-folders`. Well-known names also work, e.g. `inbox`, `sentitems`, `drafts`."
4720
+ "description": "mailFolder ID. Returned by `ask-marcel-office list-mail-folders`. Well-known names also work, e.g. `inbox`, `sentitems`, `drafts`."
4559
4721
  },
4560
4722
  {
4561
4723
  "name": "top",
@@ -4594,7 +4756,7 @@
4594
4756
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4595
4757
  }
4596
4758
  ],
4597
- "example": "ask-marcel list-mail-folder-messages --mail-folder-id 'inbox'",
4759
+ "example": "ask-marcel-office list-mail-folder-messages --mail-folder-id 'inbox'",
4598
4760
  "responseShape": "collection of Microsoft Graph `message` resources under `value[]`",
4599
4761
  "pagination": true
4600
4762
  },
@@ -4655,7 +4817,7 @@
4655
4817
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4656
4818
  }
4657
4819
  ],
4658
- "example": "ask-marcel list-mail-folder-messages-delta --mail-folder-id 'inbox'",
4820
+ "example": "ask-marcel-office list-mail-folder-messages-delta --mail-folder-id 'inbox'",
4659
4821
  "responseShape": "collection of Microsoft Graph `message` resources under `data.value[]`. Cursor tokens are hoisted to envelope level: top-level `nextLink` while paging, then top-level `deltaLink` on the final page (CLI strips the original `@odata.*` keys from `data`).",
4660
4822
  "pagination": true
4661
4823
  },
@@ -4704,7 +4866,7 @@
4704
4866
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4705
4867
  }
4706
4868
  ],
4707
- "example": "ask-marcel list-mail-folders",
4869
+ "example": "ask-marcel-office list-mail-folders",
4708
4870
  "responseShape": "collection of Microsoft Graph `mailFolder` resources under `value[]`",
4709
4871
  "pagination": true
4710
4872
  },
@@ -4716,7 +4878,7 @@
4716
4878
  "graphPathTemplate": "/me/mailFolders/delta()",
4717
4879
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/mailfolder-delta",
4718
4880
  "options": [],
4719
- "example": "ask-marcel list-mail-folders-delta",
4881
+ "example": "ask-marcel-office list-mail-folders-delta",
4720
4882
  "responseShape": "collection of Microsoft Graph `mailFolder` resources under `data.value[]`. Cursor tokens are hoisted to envelope level: top-level `nextLink` while paging, then top-level `deltaLink` on the final page.",
4721
4883
  "pagination": true
4722
4884
  },
@@ -4765,7 +4927,7 @@
4765
4927
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4766
4928
  }
4767
4929
  ],
4768
- "example": "ask-marcel list-mail-messages",
4930
+ "example": "ask-marcel-office list-mail-messages",
4769
4931
  "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`.",
4770
4932
  "pagination": true
4771
4933
  },
@@ -4784,7 +4946,7 @@
4784
4946
  "description": "mailFolder ID. Optional; defaults to `inbox`. In practice only `inbox` (or its resolved ID) works — Graph rejects every other folder for messageRules with `MailFolderNotSupportedError`."
4785
4947
  }
4786
4948
  ],
4787
- "example": "ask-marcel list-mail-rules",
4949
+ "example": "ask-marcel-office list-mail-rules",
4788
4950
  "responseShape": "collection of Microsoft Graph `messageRule` resources under `value[]`"
4789
4951
  },
4790
4952
  {
@@ -4832,7 +4994,7 @@
4832
4994
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4833
4995
  }
4834
4996
  ],
4835
- "example": "ask-marcel list-my-direct-reports",
4997
+ "example": "ask-marcel-office list-my-direct-reports",
4836
4998
  "responseShape": "collection of Microsoft Graph `directoryObject` resources (typically `user`) under `value[]`",
4837
4999
  "pagination": true
4838
5000
  },
@@ -4881,7 +5043,7 @@
4881
5043
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4882
5044
  }
4883
5045
  ],
4884
- "example": "ask-marcel list-my-memberships",
5046
+ "example": "ask-marcel-office list-my-memberships",
4885
5047
  "responseShape": "collection of Microsoft Graph `directoryObject` resources under `value[]`",
4886
5048
  "pagination": true
4887
5049
  },
@@ -4930,7 +5092,7 @@
4930
5092
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4931
5093
  }
4932
5094
  ],
4933
- "example": "ask-marcel list-my-transitive-memberships",
5095
+ "example": "ask-marcel-office list-my-transitive-memberships",
4934
5096
  "responseShape": "collection of Microsoft Graph `directoryObject` resources under `value[]`",
4935
5097
  "pagination": true
4936
5098
  },
@@ -4952,7 +5114,7 @@
4952
5114
  "key": "id"
4953
5115
  }
4954
5116
  ],
4955
- "description": "OneNote notebook ID. Returned by `ask-marcel list-onenote-notebooks`."
5117
+ "description": "OneNote notebook ID. Returned by `ask-marcel-office list-onenote-notebooks`."
4956
5118
  },
4957
5119
  {
4958
5120
  "name": "top",
@@ -4991,7 +5153,7 @@
4991
5153
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
4992
5154
  }
4993
5155
  ],
4994
- "example": "ask-marcel list-onenote-notebook-sections --notebook-id '1-12abc...'",
5156
+ "example": "ask-marcel-office list-onenote-notebook-sections --notebook-id '1-12abc...'",
4995
5157
  "responseShape": "collection of Microsoft Graph `onenoteSection` resources under `value[]`",
4996
5158
  "pagination": true
4997
5159
  },
@@ -5040,7 +5202,7 @@
5040
5202
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5041
5203
  }
5042
5204
  ],
5043
- "example": "ask-marcel list-onenote-notebooks",
5205
+ "example": "ask-marcel-office list-onenote-notebooks",
5044
5206
  "responseShape": "collection of Microsoft Graph `notebook` resources under `value[]`",
5045
5207
  "pagination": true
5046
5208
  },
@@ -5056,7 +5218,7 @@
5056
5218
  "name": "onenote-section-id",
5057
5219
  "key": "onenoteSectionId",
5058
5220
  "required": true,
5059
- "description": "OneNote section ID. Returned by `ask-marcel list-onenote-notebook-sections` or `list-all-onenote-sections`.",
5221
+ "description": "OneNote section ID. Returned by `ask-marcel-office list-onenote-notebook-sections` or `list-all-onenote-sections`.",
5060
5222
  "aliases": [
5061
5223
  {
5062
5224
  "name": "id",
@@ -5105,7 +5267,7 @@
5105
5267
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5106
5268
  }
5107
5269
  ],
5108
- "example": "ask-marcel list-onenote-section-pages --onenote-section-id '1-abc...'",
5270
+ "example": "ask-marcel-office list-onenote-section-pages --onenote-section-id '1-abc...'",
5109
5271
  "responseShape": "collection of Microsoft Graph `onenotePage` resources under `value[]`",
5110
5272
  "pagination": true
5111
5273
  },
@@ -5117,7 +5279,7 @@
5117
5279
  "graphPathTemplate": "/me/outlook/masterCategories",
5118
5280
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/outlookuser-list-mastercategories",
5119
5281
  "options": [],
5120
- "example": "ask-marcel list-outlook-categories",
5282
+ "example": "ask-marcel-office list-outlook-categories",
5121
5283
  "responseShape": "collection of Microsoft Graph `outlookCategory` resources under `value[]`"
5122
5284
  },
5123
5285
  {
@@ -5132,7 +5294,7 @@
5132
5294
  "name": "planner-plan-id",
5133
5295
  "key": "plannerPlanId",
5134
5296
  "required": true,
5135
- "description": "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel list-planner-tasks`.",
5297
+ "description": "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`.",
5136
5298
  "aliases": [
5137
5299
  {
5138
5300
  "name": "id",
@@ -5151,7 +5313,7 @@
5151
5313
  "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`."
5152
5314
  }
5153
5315
  ],
5154
- "example": "ask-marcel list-plan-buckets --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
5316
+ "example": "ask-marcel-office list-plan-buckets --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
5155
5317
  "responseShape": "collection of Microsoft Graph `plannerBucket` resources under `value[]`",
5156
5318
  "pagination": true
5157
5319
  },
@@ -5167,7 +5329,7 @@
5167
5329
  "name": "planner-plan-id",
5168
5330
  "key": "plannerPlanId",
5169
5331
  "required": true,
5170
- "description": "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel list-planner-tasks`.",
5332
+ "description": "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`.",
5171
5333
  "aliases": [
5172
5334
  {
5173
5335
  "name": "id",
@@ -5180,7 +5342,7 @@
5180
5342
  ]
5181
5343
  }
5182
5344
  ],
5183
- "example": "ask-marcel list-plan-tasks --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
5345
+ "example": "ask-marcel-office list-plan-tasks --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
5184
5346
  "responseShape": "collection of Microsoft Graph `plannerTask` resources under `value[]`",
5185
5347
  "pagination": true
5186
5348
  },
@@ -5199,7 +5361,7 @@
5199
5361
  "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`."
5200
5362
  }
5201
5363
  ],
5202
- "example": "ask-marcel list-planner-plans",
5364
+ "example": "ask-marcel-office list-planner-plans",
5203
5365
  "responseShape": "collection of Microsoft Graph `plannerPlan` resources under `value[]`",
5204
5366
  "pagination": true
5205
5367
  },
@@ -5248,7 +5410,7 @@
5248
5410
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5249
5411
  }
5250
5412
  ],
5251
- "example": "ask-marcel list-planner-tasks",
5413
+ "example": "ask-marcel-office list-planner-tasks",
5252
5414
  "responseShape": "collection of Microsoft Graph `plannerTask` resources under `value[]`",
5253
5415
  "pagination": true
5254
5416
  },
@@ -5291,7 +5453,7 @@
5291
5453
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5292
5454
  }
5293
5455
  ],
5294
- "example": "ask-marcel list-recent-files",
5456
+ "example": "ask-marcel-office list-recent-files",
5295
5457
  "responseShape": "collection of Microsoft Graph `driveItem` resources under `value[]`",
5296
5458
  "pagination": true
5297
5459
  },
@@ -5340,7 +5502,7 @@
5340
5502
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5341
5503
  }
5342
5504
  ],
5343
- "example": "ask-marcel list-recently-used-insights",
5505
+ "example": "ask-marcel-office list-recently-used-insights",
5344
5506
  "responseShape": "collection of Microsoft Graph `usedInsight` resources under `value[]`",
5345
5507
  "pagination": true
5346
5508
  },
@@ -5389,7 +5551,7 @@
5389
5551
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5390
5552
  }
5391
5553
  ],
5392
- "example": "ask-marcel list-relevant-people",
5554
+ "example": "ask-marcel-office list-relevant-people",
5393
5555
  "responseShape": "collection of Microsoft Graph `person` resources under `value[]`",
5394
5556
  "pagination": true
5395
5557
  },
@@ -5438,7 +5600,7 @@
5438
5600
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5439
5601
  }
5440
5602
  ],
5441
- "example": "ask-marcel list-room-lists",
5603
+ "example": "ask-marcel-office list-room-lists",
5442
5604
  "responseShape": "collection of Microsoft Graph `roomList` resources under `value[]`",
5443
5605
  "pagination": true
5444
5606
  },
@@ -5487,7 +5649,7 @@
5487
5649
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5488
5650
  }
5489
5651
  ],
5490
- "example": "ask-marcel list-rooms",
5652
+ "example": "ask-marcel-office list-rooms",
5491
5653
  "responseShape": "collection of Microsoft Graph `room` resources under `value[]`",
5492
5654
  "pagination": true
5493
5655
  },
@@ -5536,7 +5698,7 @@
5536
5698
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5537
5699
  }
5538
5700
  ],
5539
- "example": "ask-marcel list-sensitivity-labels",
5701
+ "example": "ask-marcel-office list-sensitivity-labels",
5540
5702
  "responseShape": "collection of Microsoft Graph `sensitivityLabel` resources under `value[]`",
5541
5703
  "pagination": true
5542
5704
  },
@@ -5597,7 +5759,7 @@
5597
5759
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5598
5760
  }
5599
5761
  ],
5600
- "example": "ask-marcel list-shared-calendar-events --user-id 'colleague@contoso.com'",
5762
+ "example": "ask-marcel-office list-shared-calendar-events --user-id 'colleague@contoso.com'",
5601
5763
  "responseShape": "collection of Microsoft Graph `event` resources under `value[]`",
5602
5764
  "pagination": true
5603
5765
  },
@@ -5682,7 +5844,7 @@
5682
5844
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5683
5845
  }
5684
5846
  ],
5685
- "example": "ask-marcel list-shared-calendar-view --user-id 'colleague@contoso.com' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
5847
+ "example": "ask-marcel-office list-shared-calendar-view --user-id 'colleague@contoso.com' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
5686
5848
  "responseShape": "collection of Microsoft Graph `event` resources under `value[]`",
5687
5849
  "pagination": true
5688
5850
  },
@@ -5731,7 +5893,7 @@
5731
5893
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5732
5894
  }
5733
5895
  ],
5734
- "example": "ask-marcel list-shared-insights",
5896
+ "example": "ask-marcel-office list-shared-insights",
5735
5897
  "responseShape": "collection of Microsoft Graph `sharedInsight` resources under `value[]`",
5736
5898
  "pagination": true
5737
5899
  },
@@ -5792,7 +5954,7 @@
5792
5954
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5793
5955
  }
5794
5956
  ],
5795
- "example": "ask-marcel list-shared-mailbox-folder-messages --user-id 'shared-mailbox@contoso.com' --mail-folder-id 'inbox'",
5957
+ "example": "ask-marcel-office list-shared-mailbox-folder-messages --user-id 'shared-mailbox@contoso.com' --mail-folder-id 'inbox'",
5796
5958
  "responseShape": "collection of Microsoft Graph `message` resources under `value[]`",
5797
5959
  "pagination": true
5798
5960
  },
@@ -5853,7 +6015,7 @@
5853
6015
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5854
6016
  }
5855
6017
  ],
5856
- "example": "ask-marcel list-shared-mailbox-messages --user-id 'shared-mailbox@contoso.com'",
6018
+ "example": "ask-marcel-office list-shared-mailbox-messages --user-id 'shared-mailbox@contoso.com'",
5857
6019
  "responseShape": "collection of Microsoft Graph `message` resources under `value[]`",
5858
6020
  "pagination": true
5859
6021
  },
@@ -5865,7 +6027,7 @@
5865
6027
  "graphPathTemplate": "/me/drive/sharedWithMe",
5866
6028
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/drive-sharedwithme",
5867
6029
  "options": [],
5868
- "example": "ask-marcel list-shared-with-me",
6030
+ "example": "ask-marcel-office list-shared-with-me",
5869
6031
  "responseShape": "collection of Microsoft Graph `driveItem` resources under `value[]` (each with a `remoteItem` pointer)"
5870
6032
  },
5871
6033
  {
@@ -5901,7 +6063,7 @@
5901
6063
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5902
6064
  }
5903
6065
  ],
5904
- "example": "ask-marcel list-sharepoint-list-columns --site-id 'contoso.sharepoint.com,abc...,def...' --list-id 'list-guid' --select 'name,displayName,readOnly'",
6066
+ "example": "ask-marcel-office list-sharepoint-list-columns --site-id 'contoso.sharepoint.com,abc...,def...' --list-id 'list-guid' --select 'name,displayName,readOnly'",
5905
6067
  "responseShape": "collection of Microsoft Graph `columnDefinition` resources under `value[]`"
5906
6068
  },
5907
6069
  {
@@ -5967,7 +6129,7 @@
5967
6129
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
5968
6130
  }
5969
6131
  ],
5970
- "example": "ask-marcel list-sharepoint-list-item-versions --site-id 'contoso.sharepoint.com,...' --list-id 'list-guid' --list-item-id '12'",
6132
+ "example": "ask-marcel-office list-sharepoint-list-item-versions --site-id 'contoso.sharepoint.com,...' --list-id 'list-guid' --list-item-id '12'",
5971
6133
  "responseShape": "collection of Microsoft Graph `listItemVersion` resources under `value[]`",
5972
6134
  "pagination": true
5973
6135
  },
@@ -5989,7 +6151,7 @@
5989
6151
  "key": "id"
5990
6152
  }
5991
6153
  ],
5992
- "description": "SharePoint site ID. Returned by `ask-marcel search-sharepoint-sites-by-name`."
6154
+ "description": "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
5993
6155
  },
5994
6156
  {
5995
6157
  "name": "top",
@@ -6022,7 +6184,7 @@
6022
6184
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6023
6185
  }
6024
6186
  ],
6025
- "example": "ask-marcel list-sharepoint-site-drives --site-id 'contoso.sharepoint.com,1234,5678'",
6187
+ "example": "ask-marcel-office list-sharepoint-site-drives --site-id 'contoso.sharepoint.com,1234,5678'",
6026
6188
  "responseShape": "collection of Microsoft Graph `drive` resources under `value[]`",
6027
6189
  "pagination": true
6028
6190
  },
@@ -6038,13 +6200,13 @@
6038
6200
  "name": "site-id",
6039
6201
  "key": "siteId",
6040
6202
  "required": true,
6041
- "description": "SharePoint site ID. Returned by `ask-marcel search-sharepoint-sites-by-name`."
6203
+ "description": "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
6042
6204
  },
6043
6205
  {
6044
6206
  "name": "list-id",
6045
6207
  "key": "listId",
6046
6208
  "required": true,
6047
- "description": "SharePoint list ID or display name. Returned by `ask-marcel list-sharepoint-site-lists`.",
6209
+ "description": "SharePoint list ID or display name. Returned by `ask-marcel-office list-sharepoint-site-lists`.",
6048
6210
  "argumentHint": {
6049
6211
  "kind": "idOrName"
6050
6212
  }
@@ -6080,7 +6242,7 @@
6080
6242
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6081
6243
  }
6082
6244
  ],
6083
- "example": "ask-marcel list-sharepoint-site-list-items --site-id 'contoso.sharepoint.com,1234,5678' --list-id 'Tasks'",
6245
+ "example": "ask-marcel-office list-sharepoint-site-list-items --site-id 'contoso.sharepoint.com,1234,5678' --list-id 'Tasks'",
6084
6246
  "responseShape": "collection of Microsoft Graph `listItem` resources under `value[]`",
6085
6247
  "pagination": true
6086
6248
  },
@@ -6102,7 +6264,7 @@
6102
6264
  "key": "id"
6103
6265
  }
6104
6266
  ],
6105
- "description": "SharePoint site ID. Returned by `ask-marcel search-sharepoint-sites-by-name`."
6267
+ "description": "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
6106
6268
  },
6107
6269
  {
6108
6270
  "name": "top",
@@ -6135,7 +6297,7 @@
6135
6297
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6136
6298
  }
6137
6299
  ],
6138
- "example": "ask-marcel list-sharepoint-site-lists --site-id 'contoso.sharepoint.com,1234,5678'",
6300
+ "example": "ask-marcel-office list-sharepoint-site-lists --site-id 'contoso.sharepoint.com,1234,5678'",
6139
6301
  "responseShape": "collection of Microsoft Graph `list` resources under `value[]`",
6140
6302
  "pagination": true
6141
6303
  },
@@ -6196,7 +6358,7 @@
6196
6358
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6197
6359
  }
6198
6360
  ],
6199
- "example": "ask-marcel list-sharepoint-site-onenote-notebook-sections --site-id 'contoso.sharepoint.com,...' --notebook-id 'nb1'",
6361
+ "example": "ask-marcel-office list-sharepoint-site-onenote-notebook-sections --site-id 'contoso.sharepoint.com,...' --notebook-id 'nb1'",
6200
6362
  "responseShape": "collection of Microsoft Graph `onenoteSection` resources under `value[]`",
6201
6363
  "pagination": true
6202
6364
  },
@@ -6257,7 +6419,7 @@
6257
6419
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6258
6420
  }
6259
6421
  ],
6260
- "example": "ask-marcel list-sharepoint-site-onenote-notebooks --site-id 'contoso.sharepoint.com,...'",
6422
+ "example": "ask-marcel-office list-sharepoint-site-onenote-notebooks --site-id 'contoso.sharepoint.com,...'",
6261
6423
  "responseShape": "collection of Microsoft Graph `notebook` resources under `value[]`",
6262
6424
  "pagination": true
6263
6425
  },
@@ -6324,7 +6486,7 @@
6324
6486
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6325
6487
  }
6326
6488
  ],
6327
- "example": "ask-marcel list-sharepoint-site-onenote-section-pages --site-id 'contoso.sharepoint.com,...' --onenote-section-id 's1'",
6489
+ "example": "ask-marcel-office list-sharepoint-site-onenote-section-pages --site-id 'contoso.sharepoint.com,...' --onenote-section-id 's1'",
6328
6490
  "responseShape": "collection of Microsoft Graph `onenotePage` resources under `value[]`",
6329
6491
  "pagination": true
6330
6492
  },
@@ -6379,7 +6541,7 @@
6379
6541
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6380
6542
  }
6381
6543
  ],
6382
- "example": "ask-marcel list-sharepoint-site-pages --site-id 'contoso.sharepoint.com,...'",
6544
+ "example": "ask-marcel-office list-sharepoint-site-pages --site-id 'contoso.sharepoint.com,...'",
6383
6545
  "responseShape": "collection of Microsoft Graph `sitePage` resources under `value[]`",
6384
6546
  "pagination": true
6385
6547
  },
@@ -6416,7 +6578,7 @@
6416
6578
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6417
6579
  }
6418
6580
  ],
6419
- "example": "ask-marcel list-site-columns --site-id 'contoso.sharepoint.com,...' --select 'name,displayName'",
6581
+ "example": "ask-marcel-office list-site-columns --site-id 'contoso.sharepoint.com,...' --select 'name,displayName'",
6420
6582
  "responseShape": "collection of Microsoft Graph `columnDefinition` resources under `value[]`"
6421
6583
  },
6422
6584
  {
@@ -6470,7 +6632,7 @@
6470
6632
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6471
6633
  }
6472
6634
  ],
6473
- "example": "ask-marcel list-site-content-types --site-id 'contoso.sharepoint.com,...'",
6635
+ "example": "ask-marcel-office list-site-content-types --site-id 'contoso.sharepoint.com,...'",
6474
6636
  "responseShape": "collection of Microsoft Graph `contentType` resources under `value[]`",
6475
6637
  "pagination": true
6476
6638
  },
@@ -6492,7 +6654,7 @@
6492
6654
  "key": "id"
6493
6655
  }
6494
6656
  ],
6495
- "description": "Calendar ID, or the well-known short name `primary` / `default` for the signed-in user’s default calendar. Use `ask-marcel list-calendars` to discover non-default calendar IDs."
6657
+ "description": "Calendar ID, or the well-known short name `primary` / `default` for the signed-in user’s default calendar. Use `ask-marcel-office list-calendars` to discover non-default calendar IDs."
6496
6658
  },
6497
6659
  {
6498
6660
  "name": "top",
@@ -6531,7 +6693,7 @@
6531
6693
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6532
6694
  }
6533
6695
  ],
6534
- "example": "ask-marcel list-specific-calendar-events --calendar-id 'primary'",
6696
+ "example": "ask-marcel-office list-specific-calendar-events --calendar-id 'primary'",
6535
6697
  "responseShape": "collection of Microsoft Graph `event` resources under `value[]`",
6536
6698
  "pagination": true
6537
6699
  },
@@ -6553,7 +6715,7 @@
6553
6715
  "key": "id"
6554
6716
  }
6555
6717
  ],
6556
- "description": "Calendar ID, or `primary` / `default` for the signed-in user’s default calendar. Returned by `ask-marcel list-calendars`."
6718
+ "description": "Calendar ID, or `primary` / `default` for the signed-in user’s default calendar. Returned by `ask-marcel-office list-calendars`."
6557
6719
  },
6558
6720
  {
6559
6721
  "name": "start-date-time",
@@ -6616,7 +6778,7 @@
6616
6778
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6617
6779
  }
6618
6780
  ],
6619
- "example": "ask-marcel list-specific-calendar-view --calendar-id 'primary' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
6781
+ "example": "ask-marcel-office list-specific-calendar-view --calendar-id 'primary' --start-date-time '2026-04-01T00:00:00Z' --end-date-time '2026-05-01T00:00:00Z'",
6620
6782
  "responseShape": "collection of Microsoft Graph `event` resources (single occurrences) under `value[]`"
6621
6783
  },
6622
6784
  {
@@ -6637,7 +6799,7 @@
6637
6799
  "key": "id"
6638
6800
  }
6639
6801
  ],
6640
- "description": "Microsoft Teams team ID. Returned by `ask-marcel list-joined-teams`."
6802
+ "description": "Microsoft Teams team ID. Returned by `ask-marcel-office list-joined-teams`."
6641
6803
  },
6642
6804
  {
6643
6805
  "name": "select",
@@ -6652,7 +6814,7 @@
6652
6814
  "description": "OData $filter: predicate to narrow results server-side. Quoting rules: string literals MUST use SINGLE quotes (`subject eq 'invoice'`), NOT double quotes — Graph rejects `subject eq \"invoice\"` with `InvalidFilterClause`. To embed a single quote inside a string, double it (`subject eq 'O''Brien'`). Booleans, numbers, and dates are unquoted (`isRead eq false`, `receivedDateTime ge 2026-01-01T00:00:00Z`). Wrap the whole flag value in shell DOUBLE quotes so the inner single quotes survive (`--filter \"subject eq 'invoice'\"`). Same syntax Graph documents per resource type."
6653
6815
  }
6654
6816
  ],
6655
- "example": "ask-marcel list-team-channels --team-id 'abc-1234-...'",
6817
+ "example": "ask-marcel-office list-team-channels --team-id 'abc-1234-...'",
6656
6818
  "responseShape": "collection of Microsoft Graph `channel` resources under `value[]`"
6657
6819
  },
6658
6820
  {
@@ -6676,7 +6838,7 @@
6676
6838
  "description": "Microsoft Teams team ID."
6677
6839
  }
6678
6840
  ],
6679
- "example": "ask-marcel list-team-installed-apps --team-id 'tm1'",
6841
+ "example": "ask-marcel-office list-team-installed-apps --team-id 'tm1'",
6680
6842
  "responseShape": "collection of Microsoft Graph `teamsAppInstallation` resources under `value[]`, each with an inline `teamsAppDefinition` (`displayName`, `version`, `distributionMethod`)",
6681
6843
  "pagination": true
6682
6844
  },
@@ -6731,7 +6893,7 @@
6731
6893
  "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."
6732
6894
  }
6733
6895
  ],
6734
- "example": "ask-marcel list-teams-chat-history --chat-id '19:abc...@unq.gbl.spaces' --max-pages 5",
6896
+ "example": "ask-marcel-office list-teams-chat-history --chat-id '19:abc...@unq.gbl.spaces' --max-pages 5",
6735
6897
  "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.**",
6736
6898
  "needsSubstrateToken": true,
6737
6899
  "stability": "experimental"
@@ -6757,7 +6919,7 @@
6757
6919
  "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`."
6758
6920
  }
6759
6921
  ],
6760
- "example": "ask-marcel list-teams-chat-messages --chat-id '19:abc...@unq.gbl.spaces'",
6922
+ "example": "ask-marcel-office list-teams-chat-messages --chat-id '19:abc...@unq.gbl.spaces'",
6761
6923
  "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).",
6762
6924
  "needsSubstrateToken": true,
6763
6925
  "stability": "experimental"
@@ -6783,7 +6945,7 @@
6783
6945
  "description": "Opaque pagination cursor returned in the prior response's `continuationToken` field. Omit on the first call; loop until `hasMoreData` is false."
6784
6946
  }
6785
6947
  ],
6786
- "example": "ask-marcel list-teams-chats-with-messages --page-size 100",
6948
+ "example": "ask-marcel-office list-teams-chats-with-messages --page-size 100",
6787
6949
  "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.**",
6788
6950
  "needsSubstrateToken": true,
6789
6951
  "stability": "experimental"
@@ -6800,7 +6962,7 @@
6800
6962
  "name": "todo-task-list-id",
6801
6963
  "key": "todoTaskListId",
6802
6964
  "required": true,
6803
- "description": "To Do task list ID. Returned by `ask-marcel list-todo-task-lists`.",
6965
+ "description": "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`.",
6804
6966
  "aliases": [
6805
6967
  {
6806
6968
  "name": "task-list-id",
@@ -6816,7 +6978,7 @@
6816
6978
  "name": "todo-task-id",
6817
6979
  "key": "todoTaskId",
6818
6980
  "required": true,
6819
- "description": "To Do task ID. Returned by `ask-marcel list-todo-tasks`. Accepts `--task-id` as a shorter alias (within this command's flag set the To Do context is unambiguous).",
6981
+ "description": "To Do task ID. Returned by `ask-marcel-office list-todo-tasks`. Accepts `--task-id` as a shorter alias (within this command's flag set the To Do context is unambiguous).",
6820
6982
  "aliases": [
6821
6983
  {
6822
6984
  "name": "task-id",
@@ -6861,7 +7023,7 @@
6861
7023
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6862
7024
  }
6863
7025
  ],
6864
- "example": "ask-marcel list-todo-linked-resources --todo-task-list-id 'AAMkAGI...' --todo-task-id 'AAMkABC...'",
7026
+ "example": "ask-marcel-office list-todo-linked-resources --todo-task-list-id 'AAMkAGI...' --todo-task-id 'AAMkABC...'",
6865
7027
  "responseShape": "collection of Microsoft Graph `linkedResource` resources under `value[]`",
6866
7028
  "pagination": true
6867
7029
  },
@@ -6898,7 +7060,7 @@
6898
7060
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6899
7061
  }
6900
7062
  ],
6901
- "example": "ask-marcel list-todo-task-lists",
7063
+ "example": "ask-marcel-office list-todo-task-lists",
6902
7064
  "responseShape": "collection of Microsoft Graph `todoTaskList` resources under `value[]`",
6903
7065
  "pagination": true
6904
7066
  },
@@ -6914,7 +7076,7 @@
6914
7076
  "name": "todo-task-list-id",
6915
7077
  "key": "todoTaskListId",
6916
7078
  "required": true,
6917
- "description": "To Do task list ID. Returned by `ask-marcel list-todo-task-lists`.",
7079
+ "description": "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`.",
6918
7080
  "aliases": [
6919
7081
  {
6920
7082
  "name": "id",
@@ -6967,7 +7129,7 @@
6967
7129
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
6968
7130
  }
6969
7131
  ],
6970
- "example": "ask-marcel list-todo-tasks --todo-task-list-id 'AAMkAGI...'",
7132
+ "example": "ask-marcel-office list-todo-tasks --todo-task-list-id 'AAMkAGI...'",
6971
7133
  "responseShape": "collection of Microsoft Graph `todoTask` resources under `value[]`",
6972
7134
  "pagination": true
6973
7135
  },
@@ -7000,7 +7162,7 @@
7000
7162
  ]
7001
7163
  }
7002
7164
  ],
7003
- "example": "ask-marcel list-todo-tasks-delta --todo-task-list-id 'AAMkAD...'",
7165
+ "example": "ask-marcel-office list-todo-tasks-delta --todo-task-list-id 'AAMkAD...'",
7004
7166
  "responseShape": "collection of Microsoft Graph `todoTask` resources under `data.value[]`. Cursor tokens are hoisted to envelope level: top-level `nextLink` while paging, then top-level `deltaLink` on the final page.",
7005
7167
  "pagination": true
7006
7168
  },
@@ -7049,7 +7211,7 @@
7049
7211
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
7050
7212
  }
7051
7213
  ],
7052
- "example": "ask-marcel list-trending-insights",
7214
+ "example": "ask-marcel-office list-trending-insights",
7053
7215
  "responseShape": "collection of Microsoft Graph `trending` resources under `value[]`",
7054
7216
  "pagination": true
7055
7217
  },
@@ -7110,13 +7272,13 @@
7110
7272
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
7111
7273
  }
7112
7274
  ],
7113
- "example": "ask-marcel list-user-direct-reports --user-id 'alice@contoso.com'",
7275
+ "example": "ask-marcel-office list-user-direct-reports --user-id 'alice@contoso.com'",
7114
7276
  "responseShape": "collection of Microsoft Graph `directoryObject` resources (typically `user`) under `value[]`",
7115
7277
  "pagination": true
7116
7278
  },
7117
7279
  {
7118
7280
  "name": "microsoft-search-query",
7119
- "summary": "Run a federated KQL search across the signed-in user's mail, files, list items, sites, calendar events, and people. Microsoft Graph v1.0 rejects multi-entity search bodies on most tenants (`Multiple entity search is not supported in v1.0`), so this command issues SIX parallel POSTs — one per entityType — and merges the per-entity `searchHits` containers into a single `value[]`. Each container is identifiable by the resource type inside `hits[].resource`. If a sub-request fails (e.g. tenant lacks the scope for one entity), the others still return; failures show up in `partialErrors[]`. Page size is fixed at 25 per sub-request and `top` is NOT exposed (Graph rejects $top in /search/query bodies). `chatMessage` is excluded since `Chat.Read*` is unavailable.",
7281
+ "summary": "Run a federated KQL search across the signed-in user's mail, files, list items, sites, calendar events, and people. Microsoft Graph v1.0 rejects multi-entity search bodies on most tenants (`Multiple entity search is not supported in v1.0`), so this command issues SIX parallel POSTs — one per entityType — and merges the per-entity `searchHits` containers into a single `value[]`. Each container is identifiable by the resource type inside `hits[].resource`. If a sub-request fails (e.g. tenant lacks the scope for one entity), the others still return; failures show up in `partialErrors[]`. Page size is fixed at 25 per sub-request and `top` is NOT exposed (Graph rejects $top in /search/query bodies). `chatMessage` is excluded since `Chat.Read*` is unavailable. To find Microsoft Loop pages (`.loop`) for markdown conversion, query `filetype:loop`: each `driveItem` hit carries `resource.id` plus `resource.parentReference.driveId`, the exact pair `download-drive-item-as-markdown` needs to render the page via Graph `?format=html`. (`filetype:fluid` returns nothing on this corpus; Loop pages index as `.loop`.)",
7120
7282
  "category": "meta",
7121
7283
  "graphMethod": "POST",
7122
7284
  "graphPathTemplate": "/search/query",
@@ -7129,19 +7291,19 @@
7129
7291
  "description": "KQL query string. Supports field operators where indexed by the corpus (e.g. `from:alice`, `subject:\"q3 budget\"`, `filetype:xlsx`). Free-text works everywhere."
7130
7292
  }
7131
7293
  ],
7132
- "example": "ask-marcel microsoft-search-query --query 'q3 budget'",
7294
+ "example": "ask-marcel-office microsoft-search-query --query 'q3 budget'",
7133
7295
  "responseShape": "merged Microsoft Graph `searchResponse` envelope: `{ value: [{ searchTerms, hitsContainers: [{ total, hits: [{ hitId, rank, summary, resource }] }] }, …], partialErrors?: [{ entityType, error }] }`. value[] holds one container per entityType that succeeded; partialErrors[] (only present when at least one sub-request failed) lists which entityTypes returned errors.",
7134
7296
  "bodyTemplate": "{ requests: [{ entityTypes: ['<one-of-driveItem-listItem-site-message-event-person>'], query: { queryString: '{query}' }, size: 25 }] } — sent six times in parallel, one per entityType"
7135
7297
  },
7136
7298
  {
7137
7299
  "name": "my-quick-context",
7138
- "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 Jane-session §5.2: `tenantTimeZone` lets an LLM stop treating every datetime as UTC on first contact.",
7300
+ "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). `tenantTimeZone` lets an LLM stop treating every datetime as UTC on first contact.",
7139
7301
  "category": "meta",
7140
7302
  "graphMethod": "GET",
7141
7303
  "graphPathTemplate": "(meta) parallel: /me, /me/drive, /me/mailFolders/inbox, /me/calendar, /me/planner/plans, /me/onenote/notebooks, /me/joinedTeams, /me/drive/recent, /me/mailboxSettings",
7142
7304
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/api/user-get",
7143
7305
  "options": [],
7144
- "example": "ask-marcel my-quick-context",
7306
+ "example": "ask-marcel-office my-quick-context",
7145
7307
  "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."
7146
7308
  },
7147
7309
  {
@@ -7162,7 +7324,7 @@
7162
7324
  }
7163
7325
  }
7164
7326
  ],
7165
- "example": "ask-marcel next-page --url 'https://graph.microsoft.com/v1.0/me/messages?$skip=10'",
7327
+ "example": "ask-marcel-office next-page --url 'https://graph.microsoft.com/v1.0/me/messages?$skip=10'",
7166
7328
  "responseShape": "same shape as the originating endpoint — `{ ok: true, data: { value: [...] }, nextLink: \"...\" }` with the cursor at envelope level."
7167
7329
  },
7168
7330
  {
@@ -7199,7 +7361,7 @@
7199
7361
  }
7200
7362
  }
7201
7363
  ],
7202
- "example": "ask-marcel read-mail-attachment --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
7364
+ "example": "ask-marcel-office read-mail-attachment --message-id 'AAMkAD...' --attachment-id 'AAMkAD...attach1'",
7203
7365
  "responseShape": "Polymorphic by attachment content-type. A zip → `{ count, files: [{ path, contentType, size, text } | { path, note }], truncated? }` (the convert-mail-attachment-zip shape). Everything else → `{ contentType: \"text/markdown\" | \"text/plain\", size, text, pageCount? }` (the convert-mail-attachment-to-markdown shape; `pageCount` present for PDF sources). Unsupported types (image / scanned PDF / legacy .ppt) return an api_error (415/400) naming the right next command.",
7204
7366
  "producesBytes": true
7205
7367
  },
@@ -7218,7 +7380,7 @@
7218
7380
  "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."
7219
7381
  }
7220
7382
  ],
7221
- "example": "ask-marcel resolve-calendar-link --url 'https://outlook.office.com/calendar/item/AAMkAGI2THVS...'",
7383
+ "example": "ask-marcel-office resolve-calendar-link --url 'https://outlook.office.com/calendar/item/AAMkAGI2THVS...'",
7222
7384
  "responseShape": "`{ eventId: string }`. `eventId` is URL-decoded and ready to pass to `get-calendar-event --event-id <id>`."
7223
7385
  },
7224
7386
  {
@@ -7236,8 +7398,8 @@
7236
7398
  "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)."
7237
7399
  }
7238
7400
  ],
7239
- "example": "ask-marcel resolve-drive-share-link --url 'https://contoso.sharepoint.com/:b:/s/team/EaB1cD2eF...?e=abc'",
7240
- "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."
7401
+ "example": "ask-marcel-office resolve-drive-share-link --url 'https://contoso.sharepoint.com/:b:/s/team/EaB1cD2eF...?e=abc'",
7402
+ "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-office 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."
7241
7403
  },
7242
7404
  {
7243
7405
  "name": "resolve-mail-link",
@@ -7254,7 +7416,7 @@
7254
7416
  "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."
7255
7417
  }
7256
7418
  ],
7257
- "example": "ask-marcel resolve-mail-link --url 'https://outlook.office.com/mail/inbox/id/AAMkAGI2THVS...'",
7419
+ "example": "ask-marcel-office resolve-mail-link --url 'https://outlook.office.com/mail/inbox/id/AAMkAGI2THVS...'",
7258
7420
  "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>`."
7259
7421
  },
7260
7422
  {
@@ -7272,19 +7434,19 @@
7272
7434
  "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=...`"
7273
7435
  }
7274
7436
  ],
7275
- "example": "ask-marcel resolve-teams-link --url 'https://teams.microsoft.com/l/message/19%3A...%40unq.gbl.spaces/1700000000000?tenantId=...&groupId=...&ctx=chat'",
7437
+ "example": "ask-marcel-office resolve-teams-link --url 'https://teams.microsoft.com/l/message/19%3A...%40unq.gbl.spaces/1700000000000?tenantId=...&groupId=...&ctx=chat'",
7276
7438
  "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."
7277
7439
  },
7278
7440
  {
7279
7441
  "name": "scopes-check",
7280
- "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 Jane-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.",
7442
+ "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 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. The `elevated` block reports whether the *separate* M365ChatClient-elevated token (needed by the historical-version download / convert commands) is cached and still usable — so a fresh process can pre-flight `deep-scan`-style workloads instead of discovering a 403 mid-run; `available:false` when it is absent, expired, or within the same 5-minute buffer the download path applies. The `chatsvcagg` and `ic3` blocks report the two Teams-chat substrate tokens (used by `list-teams-chat*` / `find-chats-with-user`) the same way; both self-heal from the shared refresh token, so they are informational rather than a preflight gate.",
7281
7443
  "category": "meta",
7282
7444
  "graphMethod": "GET",
7283
7445
  "graphPathTemplate": "(meta) cached-token introspection — no Graph endpoint",
7284
7446
  "graphDocsUrl": "https://learn.microsoft.com/en-us/graph/permissions-reference",
7285
7447
  "options": [],
7286
- "example": "ask-marcel scopes-check",
7287
- "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`)."
7448
+ "example": "ask-marcel-office scopes-check",
7449
+ "responseShape": "`{ scopes: string[], audience: string, expiresAt: string (ISO 8601), expiresInSeconds: number, elevated: { available: boolean, expiresInSeconds?: number }, chatsvcagg: { available: boolean, expiresInSeconds?: number }, ic3: { available: boolean, 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`). `elevated.available` is `true` only when the cached M365ChatClient-elevated token (used by the historical-version commands) is present and beyond the 5-minute buffer; `elevated.expiresInSeconds` is its raw remaining seconds and is omitted (the key is absent) when no elevated token is cached. `chatsvcagg` and `ic3` are the two Teams-chat substrate tokens, same shape as `elevated`; both self-heal from the shared refresh token, so they are informational rather than a preflight gate."
7288
7450
  },
7289
7451
  {
7290
7452
  "name": "search-all-accessible-sites",
@@ -7307,7 +7469,7 @@
7307
7469
  "description": "Pass `--count-files true` to add `estimatedFileCount` to each kept site — the Microsoft Search index's security-trimmed `driveItem` total (files + folders) scoped to that site's `webUrl` via KQL `path:`. OFF by default because it issues ONE extra Search query per site (chunked, capped at 200) — a real fan-out with 429-throttling risk; narrow with `--query` first. It is an estimate, not an exact count."
7308
7470
  }
7309
7471
  ],
7310
- "example": "ask-marcel search-all-accessible-sites --output json",
7472
+ "example": "ask-marcel-office search-all-accessible-sites --output json",
7311
7473
  "responseShape": "`{ value: [<Microsoft Graph site resource: { id, name, displayName?, webUrl, size?, estimatedFileCount?, … }>], count, fileEstimate?, archivedExcluded?, nonNavigableExcluded?, notFoundExcluded?, archiveProbeErrors?, truncated?: true, archiveProbeTruncated?: true }`. `estimatedFileCount` appears only with `--count-files true` — the security-trimmed `driveItem` (files+folders) estimate scoped to each site, omitted past the 200-site count cap or when the per-site query fails. `value[]` is deduped by site `id` across pages; `count` is the number of distinct sites returned (the authoritative figure). `size` (when present) is the site's DEFAULT document library's total bytes used (`drive.quota.used`, recursive) — folded onto the same per-site probe for free, omitted for sites past the probe ceiling or without a default drive; it is a data-volume signal, not a file count. `fileEstimate` (best-effort, omitted if the extra query fails) is the Microsoft Search index's security-trimmed `driveItem` count — roughly how many files+folders the user can access across all of SharePoint/OneDrive. `truncated: true` means paging stopped early (page ceiling hit, or a later page errored) — narrow with `--query` to see the rest; its absence means the sweep ran to completion. `archivedExcluded` (omitted when 0) counts sites dropped as archived/locked by the per-site probe; `nonNavigableExcluded` counts sites dropped by URL shape (add-in app domains, `/contentstorage/` SharePoint Embedded containers, `/_layouts/` system pages); `notFoundExcluded` counts sites whose probe returned 404. `archiveProbeErrors` (omitted when 0) counts sites whose probe failed for an unrelated reason — those are KEPT, so an archived one could slip through. `archiveProbeTruncated: true` means more sites were returned than the probe ceiling (250); the overflow is kept unprobed — narrow with `--query`.",
7312
7474
  "bodyTemplate": "{ requests: [{ entityTypes: ['site'], query: { queryString: '{query}' }, from: <page*25>, size: 25 }] } — `{query}` defaults to `*` (all accessible sites); re-issued per page, advancing `from` by 25 until `moreResultsAvailable` is false"
7313
7475
  },
@@ -7362,7 +7524,7 @@
7362
7524
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
7363
7525
  }
7364
7526
  ],
7365
- "example": "ask-marcel search-mail-messages --query 'from:alice subject:Q3'",
7527
+ "example": "ask-marcel-office search-mail-messages --query 'from:alice subject:Q3'",
7366
7528
  "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`.",
7367
7529
  "pagination": true
7368
7530
  },
@@ -7411,7 +7573,7 @@
7411
7573
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
7412
7574
  }
7413
7575
  ],
7414
- "example": "ask-marcel search-my-documents --query 'q1 budget'",
7576
+ "example": "ask-marcel-office search-my-documents --query 'q1 budget'",
7415
7577
  "responseShape": "collection of Microsoft Graph `driveItem` resources under `value[]`",
7416
7578
  "pagination": true
7417
7579
  },
@@ -7433,7 +7595,7 @@
7433
7595
  "key": "id"
7434
7596
  }
7435
7597
  ],
7436
- "description": "Microsoft Graph drive ID to search inside. Use `ask-marcel list-drives` for the personal OneDrive, or `ask-marcel list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
7598
+ "description": "Microsoft Graph drive ID to search inside. Use `ask-marcel-office list-drives` for the personal OneDrive, or `ask-marcel-office list-sharepoint-site-drives --site-id <id>` for a SharePoint document library."
7437
7599
  },
7438
7600
  {
7439
7601
  "name": "query",
@@ -7472,7 +7634,7 @@
7472
7634
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
7473
7635
  }
7474
7636
  ],
7475
- "example": "ask-marcel search-onedrive-files --drive-id 'b!1234' --query 'q1 budget'",
7637
+ "example": "ask-marcel-office search-onedrive-files --drive-id 'b!1234' --query 'q1 budget'",
7476
7638
  "responseShape": "collection of Microsoft Graph `driveItem` resources under `value[]`",
7477
7639
  "pagination": true
7478
7640
  },
@@ -7527,7 +7689,7 @@
7527
7689
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
7528
7690
  }
7529
7691
  ],
7530
- "example": "ask-marcel search-onenote-pages --title-substring 'meeting notes' --top 25",
7692
+ "example": "ask-marcel-office search-onenote-pages --title-substring 'meeting notes' --top 25",
7531
7693
  "responseShape": "collection of Microsoft Graph `onenotePage` resources under `value[]` whose title contains the substring",
7532
7694
  "pagination": true
7533
7695
  },
@@ -7582,7 +7744,7 @@
7582
7744
  "description": "OData $expand: navigation properties to include inline (e.g. `attachments`). Increases response size; use sparingly."
7583
7745
  }
7584
7746
  ],
7585
- "example": "ask-marcel search-sharepoint-sites-by-name --query 'marketing'",
7747
+ "example": "ask-marcel-office search-sharepoint-sites-by-name --query 'marketing'",
7586
7748
  "responseShape": "collection of Microsoft Graph `site` resources under `value[]` (up to 25), each carrying `size?` — its default document library's total bytes used (`drive.quota.used`, recursive), folded onto the same probe for free (a data-volume signal, not a file count; omitted when the site has no default drive). Sites you cannot open are excluded: `nonNavigableExcluded` drops add-in app domains, `/contentstorage/` (SharePoint Embedded) containers, and `/_layouts/` system URLs by URL shape (no probe); each remaining match is probed (`GET /sites/{id}?$select=…,siteCollection&$expand=drive($select=quota)`) and `archivedExcluded` drops archived / `423 resourceLocked` sites while `notFoundExcluded` drops probes that 404. All three counters are omitted when 0. `archiveProbeErrors` (omitted when 0) counts matches kept because their probe failed for an unrelated reason. Active personal OneDrives are kept.",
7587
7749
  "pagination": true
7588
7750
  },
@@ -7667,7 +7829,7 @@
7667
7829
  }
7668
7830
  }
7669
7831
  ],
7670
- "example": "ask-marcel update-mail-draft --message-id \"AAMkAD...\" --subject \"Updated: Q3 Report\" --to-recipients \"alice@example.com,charlie@example.com\"",
7832
+ "example": "ask-marcel-office update-mail-draft --message-id \"AAMkAD...\" --subject \"Updated: Q3 Report\" --to-recipients \"alice@example.com,charlie@example.com\"",
7671
7833
  "responseShape": "The updated Microsoft Graph message object: `{ id, subject, body, from, toRecipients, ccRecipients, bccRecipients, receivedDateTime, isDraft, … }`. Graph returns 204 No Content on success with no body — the CLI surfaces `{ ok: true }` in that case.",
7672
7834
  "bodyTemplate": "{ subject?: '{subject}', body?: { contentType: '{body-content-type}', content: '{body-content}' }, toRecipients?: '{to-recipients}', ccRecipients?: '{cc-recipients}', bccRecipients?: '{bcc-recipients}', importance?: '{importance}' } — only provided fields are sent",
7673
7835
  "mutates": true