ask-marcel-office-cli 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1910,14 +1910,6 @@ var createNodeProcessRunner = () => ({
1910
1910
  }
1911
1911
  })
1912
1912
  });
1913
- // src/use-cases/commands/download-drive-item-as-markdown.ts
1914
- var exports_download_drive_item_as_markdown = {};
1915
- __export(exports_download_drive_item_as_markdown, {
1916
- schema: () => schema,
1917
- meta: () => meta3,
1918
- execute: () => execute
1919
- });
1920
-
1921
1913
  // node_modules/zod/v4/classic/external.js
1922
1914
  var exports_external = {};
1923
1915
  __export(exports_external, {
@@ -15450,8 +15442,50 @@ function date4(params) {
15450
15442
 
15451
15443
  // node_modules/zod/v4/classic/external.js
15452
15444
  config(en_default());
15445
+ // src/use-cases/commands/reject-unknown-params.ts
15446
+ var camelToKebab = (value) => value.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
15447
+ var allowedKeys = (schema) => {
15448
+ if (!(schema instanceof exports_external.ZodObject))
15449
+ return [];
15450
+ return Object.keys(schema.shape);
15451
+ };
15452
+ var unknownParamError = (unknown2, allowed) => {
15453
+ const named = unknown2.map((k) => `--${camelToKebab(k)}`).join(", ");
15454
+ const supported = allowed.map((k) => `--${camelToKebab(k)}`).toSorted((a, b) => a.localeCompare(b)).join(", ");
15455
+ return {
15456
+ type: "validation_error",
15457
+ code: "unknown_parameter",
15458
+ message: `${named} ${unknown2.length === 1 ? "is not a parameter" : "are not parameters"} of this command, so it would have been ignored rather than applied. Supported: ${supported || "(none)"}.`
15459
+ };
15460
+ };
15461
+ var rejectUnknownParams = (schema, params) => {
15462
+ const allowed = allowedKeys(schema);
15463
+ if (allowed.length === 0)
15464
+ return;
15465
+ const unknown2 = Object.keys(params).filter((key) => !allowed.includes(key));
15466
+ if (unknown2.length === 0)
15467
+ return;
15468
+ return err(unknownParamError(unknown2, allowed));
15469
+ };
15470
+ var withUnknownParamRejection = (command) => {
15471
+ const { executeLocal } = command;
15472
+ return {
15473
+ ...command,
15474
+ execute: async (graph, params) => rejectUnknownParams(command.schema, params) ?? await command.execute(graph, params),
15475
+ ...executeLocal === undefined ? {} : { executeLocal: async (fs, params) => rejectUnknownParams(command.schema, params) ?? await executeLocal(fs, params) }
15476
+ };
15477
+ };
15478
+
15479
+ // src/use-cases/commands/download-drive-item-as-markdown.ts
15480
+ var exports_download_drive_item_as_markdown = {};
15481
+ __export(exports_download_drive_item_as_markdown, {
15482
+ schema: () => schema,
15483
+ meta: () => meta3,
15484
+ execute: () => execute
15485
+ });
15486
+
15453
15487
  // src/use-cases/commands/format-zod-error.ts
15454
- var camelToKebab = (s) => s.replaceAll(/([A-Z])/g, "-$1").toLowerCase();
15488
+ var camelToKebab2 = (s) => s.replaceAll(/([A-Z])/g, "-$1").toLowerCase();
15455
15489
  var humanize = (issue2) => {
15456
15490
  if (issue2.code === "invalid_type")
15457
15491
  return "is missing";
@@ -15470,7 +15504,7 @@ var formatZodError = (error48) => {
15470
15504
  if (issue2.path.length === 0)
15471
15505
  return `<root>: ${issue2.message}`;
15472
15506
  const path = renderPath(issue2.path);
15473
- const flag = `--${camelToKebab(path)}`;
15507
+ const flag = `--${camelToKebab2(path)}`;
15474
15508
  return `${flag} ${humanize(issue2)}`;
15475
15509
  }).join("; ");
15476
15510
  };
@@ -18201,7 +18235,6 @@ var execute6 = async (graph, params) => {
18201
18235
  var meta8 = {
18202
18236
  summary: 'Download the binary content of a file stored in OneDrive / SharePoint, with the bytes inlined. The CLI follows the Graph 302 → SharePoint media-transform redirect internally so the LLM never has to fetch an external URL. The bytes are CONTENT-SNIFFED, not judged by extension: if they decode as valid UTF-8 they come back as `{contentType: "text/plain", size, text}` (avoids ~33% base64 bloat, works for any text file regardless of name); otherwise as `{contentType, size, base64}`. A binary file that happens to be named `.txt` is returned faithfully as base64 — never silently corrupted into `�` by a forced text decode.',
18203
18237
  category: "drive",
18204
- commandAliases: ["download-onedrive-file-content"],
18205
18238
  graphMethod: "GET",
18206
18239
  graphPathTemplate: "/drives/{drive-id}/items/{item-id}/content",
18207
18240
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/api/driveitem-get-content",
@@ -18475,7 +18508,6 @@ var meta9 = {
18475
18508
  name: "event-id",
18476
18509
  key: "eventId",
18477
18510
  required: true,
18478
- aliases: [{ name: "id", key: "id" }],
18479
18511
  description: "Microsoft Graph event ID. Returned by `ask-marcel-office list-calendar-events` in the `id` field of each event."
18480
18512
  },
18481
18513
  ...selectExpandOptions
@@ -18661,8 +18693,8 @@ var meta10 = {
18661
18693
  graphPathTemplate: "/me/calendarView?startDateTime={start-date-time}&endDateTime={end-date-time}",
18662
18694
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/api/user-list-calendarview",
18663
18695
  options: [
18664
- { name: "start-date-time", key: "startDateTime", required: true, aliases: [{ name: "start", key: "start" }], description: `Lower bound. ${RELATIVE_DATE_DESCRIPTION}` },
18665
- { name: "end-date-time", key: "endDateTime", required: true, aliases: [{ name: "end", key: "end" }], description: `Upper bound. ${RELATIVE_DATE_DESCRIPTION}` },
18696
+ { name: "start-date-time", key: "startDateTime", required: true, description: `Lower bound. ${RELATIVE_DATE_DESCRIPTION}` },
18697
+ { name: "end-date-time", key: "endDateTime", required: true, description: `Upper bound. ${RELATIVE_DATE_DESCRIPTION}` },
18666
18698
  ...odataQueryOptions
18667
18699
  ],
18668
18700
  example: "ask-marcel-office list-calendar-view --start-date-time 'start-of-week' --end-date-time 'end-of-week'",
@@ -18698,7 +18730,7 @@ __export(exports_get_drive_delta, {
18698
18730
  execute: () => execute10
18699
18731
  });
18700
18732
  var baseSchema4 = exports_external.object({ driveId: exports_external.string().min(1), itemId: exports_external.string().min(1) });
18701
- var { execute: execute10, schema: schema10 } = buildNoSkipListCommand((p) => `/drives/${p.driveId}/items/${p.itemId}/delta()`, baseSchema4);
18733
+ var { execute: execute10, schema: schema10 } = buildPickODataListCommand((p) => `/drives/${p.driveId}/items/${p.itemId}/delta()`, baseSchema4, ["top", "select", "expand"]);
18702
18734
  var meta12 = {
18703
18735
  summary: "Get the incremental change set (added / modified / deleted items) under a OneDrive / SharePoint folder. Use the `@odata.deltaLink` from a previous response to resume.",
18704
18736
  category: "drive",
@@ -18716,10 +18748,9 @@ var meta12 = {
18716
18748
  name: "item-id",
18717
18749
  key: "itemId",
18718
18750
  required: true,
18719
- description: "driveItem ID of the folder whose subtree to track. Use the root folder ID from `get-drive-root-item` to track the entire drive. Accepts `--folder-id` as an alias for parity with `list-folder-files` (same concept, same flag name).",
18720
- aliases: [{ name: "folder-id", key: "folderId" }]
18751
+ description: "driveItem ID of the folder whose subtree to track. Use the root folder ID from `get-drive-root-item` to track the entire drive."
18721
18752
  },
18722
- ...noSkipOptions
18753
+ ...pickODataOptions(["top", "select", "expand"])
18723
18754
  ],
18724
18755
  example: "ask-marcel-office get-drive-delta --drive-id 'b!1234' --item-id '01ROOT'",
18725
18756
  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.",
@@ -18777,7 +18808,6 @@ var meta14 = {
18777
18808
  name: "drive-id",
18778
18809
  key: "driveId",
18779
18810
  required: true,
18780
- aliases: [{ name: "id", key: "id" }],
18781
18811
  description: DRIVE_ID_DESCRIPTION
18782
18812
  },
18783
18813
  ...selectExpandOptions
@@ -19045,8 +19075,7 @@ var meta19 = {
19045
19075
  name: "message-id",
19046
19076
  key: "messageId",
19047
19077
  required: true,
19048
- aliases: [{ name: "id", key: "id" }],
19049
- description: "Outlook message ID. Returned by `ask-marcel-office list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
19078
+ description: "Outlook message ID. Returned by `ask-marcel-office list-mail-messages` or `list-mail-folder-messages`."
19050
19079
  },
19051
19080
  ...selectExpandOptions
19052
19081
  ],
@@ -19252,8 +19281,7 @@ var meta20 = {
19252
19281
  name: "message-id",
19253
19282
  key: "messageId",
19254
19283
  required: true,
19255
- aliases: [{ name: "id", key: "id" }],
19256
- description: "Outlook message ID. Returned by `list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
19284
+ description: "Outlook message ID. Returned by `list-mail-messages` or `list-mail-folder-messages`."
19257
19285
  },
19258
19286
  {
19259
19287
  name: "inline-images",
@@ -19390,8 +19418,7 @@ var meta21 = {
19390
19418
  name: "message-id",
19391
19419
  key: "messageId",
19392
19420
  required: false,
19393
- aliases: [{ name: "id", key: "id" }],
19394
- description: "Read the signature from THIS message instead of scanning the sent folder. Use when the scan finds nothing (the message was composed in Outlook desktop) or to pin a specific signature. Source from list-mail-folder-messages --mail-folder-id sentitems. Accepts `--id` as an alias.",
19421
+ description: "Read the signature from THIS message instead of scanning the sent folder. Use when the scan finds nothing (the message was composed in Outlook desktop) or to pin a specific signature. Source from list-mail-folder-messages --mail-folder-id sentitems.",
19395
19422
  argumentHint: { kind: "idOrName" }
19396
19423
  }
19397
19424
  ],
@@ -19650,11 +19677,7 @@ var meta25 = {
19650
19677
  name: "onenote-page-id",
19651
19678
  key: "onenotePageId",
19652
19679
  required: true,
19653
- description: "OneNote page ID. Returned by `ask-marcel-office list-onenote-section-pages`.",
19654
- aliases: [
19655
- { name: "id", key: "id" },
19656
- { name: "page-id", key: "pageId" }
19657
- ]
19680
+ description: "OneNote page ID. Returned by `ask-marcel-office list-onenote-section-pages`."
19658
19681
  },
19659
19682
  {
19660
19683
  name: "inline-images",
@@ -19701,11 +19724,7 @@ var meta26 = {
19701
19724
  name: "onenote-page-id",
19702
19725
  key: "onenotePageId",
19703
19726
  required: true,
19704
- description: "OneNote page ID. Returned by `ask-marcel-office list-onenote-section-pages`.",
19705
- aliases: [
19706
- { name: "id", key: "id" },
19707
- { name: "page-id", key: "pageId" }
19708
- ]
19727
+ description: "OneNote page ID. Returned by `ask-marcel-office list-onenote-section-pages`."
19709
19728
  }
19710
19729
  ],
19711
19730
  example: "ask-marcel-office get-onenote-page-content --onenote-page-id '1-abc...'",
@@ -19733,11 +19752,7 @@ var meta27 = {
19733
19752
  name: "planner-bucket-id",
19734
19753
  key: "plannerBucketId",
19735
19754
  required: true,
19736
- description: "Planner bucket ID. Returned by `ask-marcel-office list-plan-buckets`.",
19737
- aliases: [
19738
- { name: "id", key: "id" },
19739
- { name: "bucket-id", key: "bucketId" }
19740
- ]
19755
+ description: "Planner bucket ID. Returned by `ask-marcel-office list-plan-buckets`."
19741
19756
  }
19742
19757
  ],
19743
19758
  example: "ask-marcel-office get-planner-bucket --planner-bucket-id 'sFNeQRFu_kqhxpwwAhmA15gAGfoT'",
@@ -19764,11 +19779,7 @@ var meta28 = {
19764
19779
  name: "planner-plan-id",
19765
19780
  key: "plannerPlanId",
19766
19781
  required: true,
19767
- description: "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`.",
19768
- aliases: [
19769
- { name: "id", key: "id" },
19770
- { name: "plan-id", key: "planId" }
19771
- ]
19782
+ description: "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`."
19772
19783
  }
19773
19784
  ],
19774
19785
  example: "ask-marcel-office get-planner-plan --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
@@ -19795,11 +19806,7 @@ var meta29 = {
19795
19806
  name: "planner-task-id",
19796
19807
  key: "plannerTaskId",
19797
19808
  required: true,
19798
- 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).",
19799
- aliases: [
19800
- { name: "id", key: "id" },
19801
- { name: "task-id", key: "taskId" }
19802
- ]
19809
+ description: "Planner task ID. Returned by `ask-marcel-office list-planner-tasks` or `list-plan-tasks`."
19803
19810
  }
19804
19811
  ],
19805
19812
  example: "ask-marcel-office get-planner-task-details --planner-task-id '01tx7Ic7-USXEwt0lvR1cmgAH8gK'",
@@ -19826,11 +19833,7 @@ var meta30 = {
19826
19833
  name: "planner-task-id",
19827
19834
  key: "plannerTaskId",
19828
19835
  required: true,
19829
- 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).",
19830
- aliases: [
19831
- { name: "id", key: "id" },
19832
- { name: "task-id", key: "taskId" }
19833
- ]
19836
+ description: "Planner task ID. Returned by `ask-marcel-office list-planner-tasks` or `list-plan-tasks`."
19834
19837
  }
19835
19838
  ],
19836
19839
  example: "ask-marcel-office get-planner-task --planner-task-id '01tx7Ic7-USXEwt0lvR1cmgAH8gK'",
@@ -19925,8 +19928,7 @@ var meta33 = {
19925
19928
  name: "list-item-id",
19926
19929
  key: "listItemId",
19927
19930
  required: true,
19928
- description: "listItem ID (typically a small integer). Returned by `ask-marcel-office list-sharepoint-site-list-items`.",
19929
- aliases: [{ name: "item-id", key: "itemId" }]
19931
+ description: "listItem ID (typically a small integer). Returned by `ask-marcel-office list-sharepoint-site-list-items`."
19930
19932
  },
19931
19933
  ...selectExpandOptions
19932
19934
  ],
@@ -19984,7 +19986,6 @@ var meta35 = {
19984
19986
  name: "site-id",
19985
19987
  key: "siteId",
19986
19988
  required: true,
19987
- aliases: [{ name: "id", key: "id" }],
19988
19989
  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."
19989
19990
  },
19990
19991
  ...selectExpandOptions
@@ -20037,21 +20038,18 @@ var meta36 = {
20037
20038
  name: "schedules",
20038
20039
  key: "schedules",
20039
20040
  required: true,
20040
- aliases: [{ name: "emails", key: "emails" }],
20041
20041
  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`."
20042
20042
  },
20043
20043
  {
20044
20044
  name: "start-date-time",
20045
20045
  key: "startDateTime",
20046
20046
  required: true,
20047
- aliases: [{ name: "start", key: "start" }],
20048
20047
  description: `Window lower bound (interpreted as UTC). ${RELATIVE_DATE_DESCRIPTION}`
20049
20048
  },
20050
20049
  {
20051
20050
  name: "end-date-time",
20052
20051
  key: "endDateTime",
20053
20052
  required: true,
20054
- aliases: [{ name: "end", key: "end" }],
20055
20053
  description: `Window upper bound (interpreted as UTC). Graph caps the span at 62 days. ${RELATIVE_DATE_DESCRIPTION}`
20056
20054
  },
20057
20055
  {
@@ -20128,11 +20126,10 @@ var meta38 = {
20128
20126
  name: "calendar-id",
20129
20127
  key: "calendarId",
20130
20128
  required: true,
20131
- aliases: [{ name: "id", key: "id" }],
20132
20129
  description: "Calendar ID, or `primary` / `default` for the signed-in user’s default calendar. Returned by `ask-marcel-office list-calendars`."
20133
20130
  },
20134
- { name: "start-date-time", key: "startDateTime", required: true, aliases: [{ name: "start", key: "start" }], description: `Lower bound. ${RELATIVE_DATE_DESCRIPTION}` },
20135
- { name: "end-date-time", key: "endDateTime", required: true, aliases: [{ name: "end", key: "end" }], description: `Upper bound. ${RELATIVE_DATE_DESCRIPTION}` },
20131
+ { name: "start-date-time", key: "startDateTime", required: true, description: `Lower bound. ${RELATIVE_DATE_DESCRIPTION}` },
20132
+ { name: "end-date-time", key: "endDateTime", required: true, description: `Upper bound. ${RELATIVE_DATE_DESCRIPTION}` },
20136
20133
  ...odataQueryOptions
20137
20134
  ],
20138
20135
  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'",
@@ -20199,7 +20196,6 @@ var meta40 = {
20199
20196
  name: "team-id",
20200
20197
  key: "teamId",
20201
20198
  required: true,
20202
- aliases: [{ name: "id", key: "id" }],
20203
20199
  description: "Microsoft Teams team ID. Returned by `ask-marcel-office list-joined-teams`."
20204
20200
  },
20205
20201
  ...selectExpandOptions
@@ -20262,18 +20258,13 @@ var meta41 = {
20262
20258
  name: "todo-task-list-id",
20263
20259
  key: "todoTaskListId",
20264
20260
  required: true,
20265
- description: "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`.",
20266
- aliases: [
20267
- { name: "task-list-id", key: "taskListId" },
20268
- { name: "todo-list-id", key: "todoListId" }
20269
- ]
20261
+ description: "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`."
20270
20262
  },
20271
20263
  {
20272
20264
  name: "todo-task-id",
20273
20265
  key: "todoTaskId",
20274
20266
  required: true,
20275
- 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).",
20276
- aliases: [{ name: "task-id", key: "taskId" }]
20267
+ description: "To Do task ID. Returned by `ask-marcel-office list-todo-tasks`."
20277
20268
  },
20278
20269
  ...selectExpandOptions
20279
20270
  ],
@@ -20354,11 +20345,10 @@ var meta43 = {
20354
20345
  name: "event-id",
20355
20346
  key: "eventId",
20356
20347
  required: true,
20357
- aliases: [{ name: "id", key: "id" }],
20358
20348
  description: "Recurring event ID. Returned by `ask-marcel-office list-specific-calendar-events`."
20359
20349
  },
20360
- { name: "start-date-time", key: "startDateTime", required: true, aliases: [{ name: "start", key: "start" }], description: `Lower bound. ${RELATIVE_DATE_DESCRIPTION}` },
20361
- { name: "end-date-time", key: "endDateTime", required: true, aliases: [{ name: "end", key: "end" }], description: `Upper bound. ${RELATIVE_DATE_DESCRIPTION}` },
20350
+ { name: "start-date-time", key: "startDateTime", required: true, description: `Lower bound. ${RELATIVE_DATE_DESCRIPTION}` },
20351
+ { name: "end-date-time", key: "endDateTime", required: true, description: `Upper bound. ${RELATIVE_DATE_DESCRIPTION}` },
20362
20352
  ...odataQueryOptions
20363
20353
  ],
20364
20354
  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'",
@@ -20460,14 +20450,12 @@ var meta46 = {
20460
20450
  name: "start-date-time",
20461
20451
  key: "startDateTime",
20462
20452
  required: true,
20463
- aliases: [{ name: "start", key: "start" }],
20464
20453
  description: `Lower bound (required on the first call only — the deltaLink token encodes it for resumes). ${RELATIVE_DATE_DESCRIPTION}`
20465
20454
  },
20466
20455
  {
20467
20456
  name: "end-date-time",
20468
20457
  key: "endDateTime",
20469
20458
  required: true,
20470
- aliases: [{ name: "end", key: "end" }],
20471
20459
  description: `Upper bound (required on the first call only — the deltaLink token encodes it for resumes). ${RELATIVE_DATE_DESCRIPTION}`
20472
20460
  },
20473
20461
  ...topOnlyOptions
@@ -20536,7 +20524,6 @@ var meta48 = {
20536
20524
  name: "chat-id",
20537
20525
  key: "chatId",
20538
20526
  required: true,
20539
- aliases: [{ name: "id", key: "id" }],
20540
20527
  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`."
20541
20528
  },
20542
20529
  ...pickODataOptions(CHAT_MEMBERS_ODATA_KEYS)
@@ -20762,8 +20749,7 @@ var meta55 = {
20762
20749
  name: "item-id",
20763
20750
  key: "itemId",
20764
20751
  required: true,
20765
- 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".',
20766
- aliases: [{ name: "folder-id", key: "folderId" }]
20752
+ 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."
20767
20753
  },
20768
20754
  ...noSkipOptions,
20769
20755
  TENANT_ID_OPTION
@@ -20843,12 +20829,7 @@ var meta57 = {
20843
20829
  name: "todo-task-list-id",
20844
20830
  key: "todoTaskListId",
20845
20831
  required: true,
20846
- 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.",
20847
- aliases: [
20848
- { name: "id", key: "id" },
20849
- { name: "task-list-id", key: "taskListId" },
20850
- { name: "todo-list-id", key: "todoListId" }
20851
- ]
20832
+ 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."
20852
20833
  },
20853
20834
  ...odataQueryOptions
20854
20835
  ],
@@ -20906,8 +20887,7 @@ var meta59 = {
20906
20887
  name: "message-id",
20907
20888
  key: "messageId",
20908
20889
  required: true,
20909
- aliases: [{ name: "id", key: "id" }],
20910
- description: "Outlook message ID. Returned by `ask-marcel-office list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
20890
+ description: "Outlook message ID. Returned by `ask-marcel-office list-mail-messages` or `list-mail-folder-messages`."
20911
20891
  },
20912
20892
  ...odataQueryOptions
20913
20893
  ],
@@ -20936,7 +20916,6 @@ var meta60 = {
20936
20916
  name: "mail-folder-id",
20937
20917
  key: "mailFolderId",
20938
20918
  required: true,
20939
- aliases: [{ name: "id", key: "id" }],
20940
20919
  description: "mailFolder ID. Returned by `ask-marcel-office list-mail-folders`. Well-known names also work, e.g. `inbox`, `sentitems`, `drafts`."
20941
20920
  },
20942
20921
  ...odataQueryOptions
@@ -20966,7 +20945,6 @@ var meta61 = {
20966
20945
  name: "mail-folder-id",
20967
20946
  key: "mailFolderId",
20968
20947
  required: true,
20969
- aliases: [{ name: "id", key: "id" }],
20970
20948
  description: "mailFolder ID. Returned by `ask-marcel-office list-mail-folders`. Well-known names also work, e.g. `inbox`, `sentitems`, `drafts`. When listing `drafts`, a `conversationId` `$filter` is not a reliable check for whether a draft already exists on a thread: reply and forward drafts can split across several conversationIds, and `$filter` on Drafts is not read-your-writes consistent. Match client-side on subject and recipients instead, or use the `find-mail-drafts` command, which does exactly that."
20971
20949
  },
20972
20950
  ...odataQueryOptions
@@ -21065,7 +21043,6 @@ var meta65 = {
21065
21043
  name: "notebook-id",
21066
21044
  key: "notebookId",
21067
21045
  required: true,
21068
- aliases: [{ name: "id", key: "id" }],
21069
21046
  description: "OneNote notebook ID. Returned by `ask-marcel-office list-onenote-notebooks`."
21070
21047
  },
21071
21048
  ...odataQueryOptions
@@ -21116,11 +21093,7 @@ var meta67 = {
21116
21093
  name: "onenote-section-id",
21117
21094
  key: "onenoteSectionId",
21118
21095
  required: true,
21119
- description: "OneNote section ID. Returned by `ask-marcel-office list-onenote-notebook-sections` or `list-all-onenote-sections`.",
21120
- aliases: [
21121
- { name: "id", key: "id" },
21122
- { name: "section-id", key: "sectionId" }
21123
- ]
21096
+ description: "OneNote section ID. Returned by `ask-marcel-office list-onenote-notebook-sections` or `list-all-onenote-sections`."
21124
21097
  },
21125
21098
  ...odataQueryOptions
21126
21099
  ],
@@ -21149,11 +21122,7 @@ var meta68 = {
21149
21122
  name: "planner-plan-id",
21150
21123
  key: "plannerPlanId",
21151
21124
  required: true,
21152
- description: "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`.",
21153
- aliases: [
21154
- { name: "id", key: "id" },
21155
- { name: "plan-id", key: "planId" }
21156
- ]
21125
+ description: "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`."
21157
21126
  },
21158
21127
  ...selectOnlyOptions
21159
21128
  ],
@@ -21182,11 +21151,7 @@ var meta69 = {
21182
21151
  name: "planner-plan-id",
21183
21152
  key: "plannerPlanId",
21184
21153
  required: true,
21185
- description: "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`.",
21186
- aliases: [
21187
- { name: "id", key: "id" },
21188
- { name: "plan-id", key: "planId" }
21189
- ]
21154
+ description: "Planner plan ID. Returned in the `planId` field of any task from `ask-marcel-office list-planner-tasks`."
21190
21155
  }
21191
21156
  ],
21192
21157
  example: "ask-marcel-office list-plan-tasks --planner-plan-id 'xqQg5FS2LkCp935s-FIFm5gAB6'",
@@ -21256,7 +21221,6 @@ var meta72 = {
21256
21221
  name: "site-id",
21257
21222
  key: "siteId",
21258
21223
  required: true,
21259
- aliases: [{ name: "id", key: "id" }],
21260
21224
  description: "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
21261
21225
  },
21262
21226
  ...noSkipOptions
@@ -21325,7 +21289,6 @@ var meta74 = {
21325
21289
  name: "site-id",
21326
21290
  key: "siteId",
21327
21291
  required: true,
21328
- aliases: [{ name: "id", key: "id" }],
21329
21292
  description: "SharePoint site ID. Returned by `ask-marcel-office search-sharepoint-sites-by-name`."
21330
21293
  },
21331
21294
  ...noSkipOptions
@@ -21360,7 +21323,6 @@ var meta75 = {
21360
21323
  name: "calendar-id",
21361
21324
  key: "calendarId",
21362
21325
  required: true,
21363
- aliases: [{ name: "id", key: "id" }],
21364
21326
  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."
21365
21327
  },
21366
21328
  ...odataQueryOptions
@@ -21390,7 +21352,6 @@ var meta76 = {
21390
21352
  name: "team-id",
21391
21353
  key: "teamId",
21392
21354
  required: true,
21393
- aliases: [{ name: "id", key: "id" }],
21394
21355
  description: "Microsoft Teams team ID. Returned by `ask-marcel-office list-joined-teams`."
21395
21356
  },
21396
21357
  ...filterSelectOptions
@@ -21419,18 +21380,13 @@ var meta77 = {
21419
21380
  name: "todo-task-list-id",
21420
21381
  key: "todoTaskListId",
21421
21382
  required: true,
21422
- description: "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`.",
21423
- aliases: [
21424
- { name: "task-list-id", key: "taskListId" },
21425
- { name: "todo-list-id", key: "todoListId" }
21426
- ]
21383
+ description: "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`."
21427
21384
  },
21428
21385
  {
21429
21386
  name: "todo-task-id",
21430
21387
  key: "todoTaskId",
21431
21388
  required: true,
21432
- 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).",
21433
- aliases: [{ name: "task-id", key: "taskId" }]
21389
+ description: "To Do task ID. Returned by `ask-marcel-office list-todo-tasks`."
21434
21390
  },
21435
21391
  ...odataQueryOptions
21436
21392
  ],
@@ -21491,12 +21447,7 @@ var meta79 = {
21491
21447
  name: "todo-task-list-id",
21492
21448
  key: "todoTaskListId",
21493
21449
  required: true,
21494
- description: "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`.",
21495
- aliases: [
21496
- { name: "id", key: "id" },
21497
- { name: "task-list-id", key: "taskListId" },
21498
- { name: "todo-list-id", key: "todoListId" }
21499
- ]
21450
+ description: "To Do task list ID. Returned by `ask-marcel-office list-todo-task-lists`."
21500
21451
  },
21501
21452
  ...odataQueryOptions
21502
21453
  ],
@@ -21647,7 +21598,6 @@ var meta83 = {
21647
21598
  name: "drive-id",
21648
21599
  key: "driveId",
21649
21600
  required: true,
21650
- aliases: [{ name: "id", key: "id" }],
21651
21601
  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."
21652
21602
  },
21653
21603
  { name: "query", key: "query", required: true, description: "Free-text search query. Matches filename, content, and metadata." },
@@ -21668,31 +21618,30 @@ __export(exports_search_onenote_pages, {
21668
21618
  });
21669
21619
  var noFilterShape = Object.fromEntries(Object.entries(odataQuerySchema.shape).filter(([key]) => key !== "filter"));
21670
21620
  var noFilterOptions = odataQueryOptions.filter((o) => o.name !== "filter");
21671
- var schema82 = exports_external.object({ titleSubstring: exports_external.string().min(1) }).extend(noFilterShape);
21621
+ var schema82 = exports_external.object({ query: exports_external.string().min(1) }).extend(noFilterShape);
21672
21622
  var execute82 = async (graph, params) => {
21673
21623
  const parsed = schema82.safeParse(params);
21674
21624
  if (!parsed.success)
21675
21625
  return err({ type: "validation_error", message: formatZodError(parsed.error) });
21676
- const path = appendOData(`/me/onenote/pages?$filter=contains(title,'${odataStringLiteral(parsed.data.titleSubstring)}')`, parsed.data);
21626
+ const path = appendOData(`/me/onenote/pages?$filter=contains(title,'${odataStringLiteral(parsed.data.query)}')`, parsed.data);
21677
21627
  return graph.get(path);
21678
21628
  };
21679
21629
  var meta84 = {
21680
21630
  summary: "Find OneNote pages whose title contains a substring (case-sensitive — page content is NOT searched). Microsoft removed full-text OneNote `?search=` from v1.0 Graph; only $filter against `title` remains, which is what this command runs. Accepts the OData passthrough flags top/skip/select/orderby/expand. The filter passthrough is intentionally omitted — the path already pins a `$filter` for the title-contains predicate, and Graph rejects two `$filter` query params.",
21681
21631
  category: "notes",
21682
21632
  graphMethod: "GET",
21683
- graphPathTemplate: "/me/onenote/pages?$filter=contains(title,'{title-substring}')",
21633
+ graphPathTemplate: "/me/onenote/pages?$filter=contains(title,'{query}')",
21684
21634
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/api/onenote-list-pages",
21685
21635
  options: [
21686
21636
  {
21687
- name: "title-substring",
21688
- key: "titleSubstring",
21637
+ name: "query",
21638
+ key: "query",
21689
21639
  required: true,
21690
- description: "Substring to look for inside OneNote page titles (case-sensitive, exact substring). " + "This is title-only — full-text body search is not available on OneNote pages in v1.0 Graph. " + "Use `list-onenote-section-pages` if you already know the section.",
21691
- aliases: [{ name: "query", key: "query" }]
21640
+ description: "Substring to look for inside OneNote page TITLES (case-sensitive, exact substring — not a full-text query, despite the flag name shared with the other search commands). " + "Full-text body search is not available on OneNote pages in v1.0 Graph. " + "Use `list-onenote-section-pages` if you already know the section."
21692
21641
  },
21693
21642
  ...noFilterOptions
21694
21643
  ],
21695
- example: "ask-marcel-office search-onenote-pages --title-substring 'meeting notes' --top 25",
21644
+ example: "ask-marcel-office search-onenote-pages --query 'meeting notes' --top 25",
21696
21645
  responseShape: "collection of Microsoft Graph `onenotePage` resources under `value[]` whose title contains the substring",
21697
21646
  pagination: true
21698
21647
  };
@@ -22642,7 +22591,6 @@ var meta92 = {
22642
22591
  name: "event-id",
22643
22592
  key: "eventId",
22644
22593
  required: true,
22645
- aliases: [{ name: "id", key: "id" }],
22646
22594
  description: "Outlook calendar event ID. Returned by `ask-marcel-office list-calendar-events` or `get-calendar-event`."
22647
22595
  },
22648
22596
  ...odataQueryOptions
@@ -22747,6 +22695,7 @@ var findBodyInsertStart = (html) => {
22747
22695
  return match === null ? 0 : match.index + match[0].length;
22748
22696
  };
22749
22697
  var commentCarriesQuoteBoundary = (commentHtml) => findQuoteBoundary(commentHtml) !== -1;
22698
+ var bodyCarriesQuote = (contentType, content) => contentType.toLowerCase() === "html" ? findQuoteBoundary(content) !== -1 : findPlainTextQuoteBoundary(content) !== -1;
22750
22699
  var boundaryMarkerRefusal = (flagName) => `${flagName} carries a quoted-reply boundary marker (a pasted gmail_quote container, an Outlook divRplyFwdMsg / appendonsend / border-top separator, or a bold From: + Sent: header pair). It would be kept verbatim, and a later \`update-mail-draft --comment\` edit would cut the draft at that marker and lose the real quoted history below it. Remove the pasted quote from your text, or pass --body-content-type Text to have it escaped into literal characters.`;
22751
22700
  var insertCommentAboveQuote = (html, commentHtml) => {
22752
22701
  const at = findBodyInsertStart(html);
@@ -22790,7 +22739,7 @@ var schema93 = exports_external.object({
22790
22739
  forwardMessageId: exports_external.string().min(1),
22791
22740
  toRecipients: exports_external.string().min(1),
22792
22741
  ccRecipients: exports_external.string().optional(),
22793
- bodyContent: exports_external.string().min(1),
22742
+ comment: exports_external.string().min(1),
22794
22743
  subject: exports_external.string().optional(),
22795
22744
  bodyContentType: exports_external.enum(["Text", "HTML"]).optional()
22796
22745
  });
@@ -22809,7 +22758,7 @@ var readDraftBody = async (graph, created, draftId) => {
22809
22758
  type: "api_error",
22810
22759
  status: 500,
22811
22760
  code: "draft_body_unreadable",
22812
- message: `Draft ${draftId} was created but its body could not be read back, so the comment was never written into it. The draft exists - review it in Outlook Drafts, or set its body with \`update-mail-draft --message-id ${draftId} --body-content ...\`.`
22761
+ message: `Draft ${draftId} was created but its body could not be read back, so the comment was never written into it. The draft exists - review it in Outlook Drafts, or revise it with \`update-mail-draft --message-id ${draftId}\` in comment mode (see \`ask-marcel-office docs update-mail-draft\`).`
22813
22762
  });
22814
22763
  }
22815
22764
  return ok(parsed.data.body);
@@ -22821,13 +22770,13 @@ var execute93 = async (graph, params) => {
22821
22770
  type: "validation_error",
22822
22771
  message: formatZodError(parsed.error)
22823
22772
  });
22824
- const { forwardMessageId, toRecipients, ccRecipients, bodyContent, subject, bodyContentType } = parsed.data;
22773
+ const { forwardMessageId, toRecipients, ccRecipients, comment, subject, bodyContentType } = parsed.data;
22825
22774
  const asHtml = bodyContentType === "HTML";
22826
- if (asHtml && commentCarriesQuoteBoundary(bodyContent)) {
22827
- return err({ type: "validation_error", message: boundaryMarkerRefusal("--body-content") });
22775
+ if (asHtml && commentCarriesQuoteBoundary(comment)) {
22776
+ return err({ type: "validation_error", message: boundaryMarkerRefusal("--comment") });
22828
22777
  }
22829
22778
  const created = await graph.post(`/me/messages/${forwardMessageId}/createForward`, {
22830
- comment: asHtml ? "" : bodyContent,
22779
+ comment: asHtml ? "" : comment,
22831
22780
  toRecipients: parseRecipients2(toRecipients)
22832
22781
  });
22833
22782
  if (!created.ok)
@@ -22857,10 +22806,10 @@ var execute93 = async (graph, params) => {
22857
22806
  if (draftBody.value.contentType.toLowerCase() !== "html") {
22858
22807
  return err({
22859
22808
  type: "validation_error",
22860
- message: `The forwarded draft's body is ${draftBody.value.contentType}, not HTML, so HTML cannot be placed above the quoted original without rewriting it. Draft ${draftId} was already created - set its text with \`update-mail-draft --message-id ${draftId} --comment "..."\`, or delete it in Outlook Drafts and retry without --body-content-type HTML.`
22809
+ message: `The forwarded draft's body is ${draftBody.value.contentType}, not HTML, so HTML cannot be placed above the quoted original without rewriting it. Draft ${draftId} was already created - revise it with \`update-mail-draft --message-id ${draftId}\` in comment mode, or delete it in Outlook Drafts and retry without --body-content-type HTML.`
22861
22810
  });
22862
22811
  }
22863
- const spliced = insertCommentAboveQuote(draftBody.value.content, bodyContent);
22812
+ const spliced = insertCommentAboveQuote(draftBody.value.content, comment);
22864
22813
  const patch = { body: { contentType: "HTML", content: spliced.html } };
22865
22814
  if (ccRecipients)
22866
22815
  patch.ccRecipients = parseRecipients2(ccRecipients);
@@ -22879,8 +22828,7 @@ var meta95 = {
22879
22828
  name: "forward-message-id",
22880
22829
  key: "forwardMessageId",
22881
22830
  required: true,
22882
- aliases: [{ name: "id", key: "id" }],
22883
- description: "The message being forwarded. Source from list-mail-folder-messages or search-mail-messages. Accepts `--id` as an alias.",
22831
+ description: "The message being forwarded. Source from list-mail-folder-messages or search-mail-messages.",
22884
22832
  argumentHint: { kind: "idOrName" }
22885
22833
  },
22886
22834
  {
@@ -22896,10 +22844,10 @@ var meta95 = {
22896
22844
  description: "Comma-separated list of CC recipient email addresses."
22897
22845
  },
22898
22846
  {
22899
- name: "body-content",
22900
- key: "bodyContent",
22847
+ name: "comment",
22848
+ key: "comment",
22901
22849
  required: true,
22902
- description: "The comment text, placed above the quoted forwarded message. Plain text by default; pass --body-content-type HTML to send it as markup."
22850
+ description: "The comment text, placed above the quoted forwarded message. Named for Graph's own createForward payload field, and the same word update-mail-draft uses for the same role. Plain text by default; pass --body-content-type HTML to send it as markup."
22903
22851
  },
22904
22852
  {
22905
22853
  name: "subject",
@@ -22911,12 +22859,12 @@ var meta95 = {
22911
22859
  name: "body-content-type",
22912
22860
  key: "bodyContentType",
22913
22861
  required: false,
22914
- description: "Format of --body-content: Text (default) or HTML. Text is handed to Graph as the forward comment, which HTML-escapes it, so markup shows as literal characters. HTML instead creates the draft with an empty comment and splices your markup in at the TOP of the body — above Graph's separator (the `<hr>` line) and the forwarded original, so your comment leads the body content — leaving the original and its styles byte-identical. Rejected when your markup itself contains a quote boundary marker (a pasted reply chain), and when the original is a plain-text message.",
22862
+ description: "Format of --comment: Text (default) or HTML. Text is handed to Graph as the forward comment, which HTML-escapes it, so markup shows as literal characters. HTML instead creates the draft with an empty comment and splices your markup in at the TOP of the body — above Graph's separator (the `<hr>` line) and the forwarded original, so your comment leads the body content — leaving the original and its styles byte-identical. Rejected when your markup itself contains a quote boundary marker (a pasted reply chain), and when the original is a plain-text message.",
22915
22863
  argumentHint: { kind: "magicValue", values: ["Text", "HTML"] }
22916
22864
  }
22917
22865
  ],
22918
- 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."',
22919
- bodyTemplate: "Text: POST { comment: '{body-content}', toRecipients: '{to-recipients}' } then optional PATCH { ccRecipients?: '{cc-recipients}', subject?: '{subject}' }. HTML ({body-content-type}): POST { comment: '', toRecipients: '{to-recipients}' } then ONE PATCH { body: { contentType: 'HTML', content: <'{body-content}' spliced at the top of the body, above Graph's <hr> separator and the quote> }, ccRecipients?: '{cc-recipients}', subject?: '{subject}' }",
22866
+ example: 'ask-marcel-office create-forward-draft --forward-message-id "AAMkAD..." --to-recipients "bob@example.com" --comment "Bob owns this now, forwarding for your action."',
22867
+ bodyTemplate: "Text: POST { comment: '{comment}', toRecipients: '{to-recipients}' } then optional PATCH { ccRecipients?: '{cc-recipients}', subject?: '{subject}' }. HTML ({body-content-type}): POST { comment: '', toRecipients: '{to-recipients}' } then ONE PATCH { body: { contentType: 'HTML', content: <'{comment}' spliced at the top of the body, above Graph's <hr> separator and the quote> }, ccRecipients?: '{cc-recipients}', subject?: '{subject}' }",
22920
22868
  mutates: true,
22921
22869
  scopesRequired: ["Mail.ReadWrite"],
22922
22870
  responseShape: "A confirmation of the write, NOT the whole message: `{ id, subject, toRecipients, ccRecipients, bccRecipients, importance, bodyPreview, isDraft, webLink, conversationId }` (only the fields Graph returned; `{ ok: true }` when Graph answers 204). The `body` is deliberately omitted — you just wrote it, and echoing a long thread's quoted history back cost ~174 KB of context per call. Read the full body with `get-mail-message --id <the returned id>` when you actually need it; `bodyPreview` is Graph's ~255-char summary, enough to confirm WHICH draft answered. The `id` is the draft — refine it with `update-mail-draft`, or open Outlook Drafts to review and send. Dedup caveat: a `conversationId` `$filter` on the Drafts folder is not a reliable 'does a draft already exist on this thread' check. Reply and forward drafts do not always inherit the inbound message's `conversationId` (one thread can split across several), and Graph `$filter` on Drafts is not read-your-writes consistent, so a just-created draft can be missed. To find existing drafts, use the `find-mail-drafts` command, which scans recent drafts and matches client-side on subject and recipients; to revise a draft this session created, reuse the returned `id`."
@@ -23036,7 +22984,7 @@ __export(exports_create_reply_draft, {
23036
22984
  });
23037
22985
  var schema95 = exports_external.object({
23038
22986
  replyToMessageId: exports_external.string().min(1),
23039
- bodyContent: exports_external.string().min(1),
22987
+ comment: exports_external.string().min(1),
23040
22988
  subject: exports_external.string().optional(),
23041
22989
  replyAll: exports_external.enum(["true", "false"]).optional(),
23042
22990
  bodyContentType: exports_external.enum(["Text", "HTML"]).optional()
@@ -23056,7 +23004,7 @@ var readDraftBody2 = async (graph, created, draftId) => {
23056
23004
  type: "api_error",
23057
23005
  status: 500,
23058
23006
  code: "draft_body_unreadable",
23059
- message: `Draft ${draftId} was created but its body could not be read back, so the reply text was never written into it. The draft exists - review it in Outlook Drafts, or set its body with \`update-mail-draft --message-id ${draftId} --body-content ...\`.`
23007
+ message: `Draft ${draftId} was created but its body could not be read back, so the reply text was never written into it. The draft exists - review it in Outlook Drafts, or revise it with \`update-mail-draft --message-id ${draftId}\` in comment mode (see \`ask-marcel-office docs update-mail-draft\`).`
23060
23008
  });
23061
23009
  }
23062
23010
  return ok(parsed.data.body);
@@ -23065,13 +23013,13 @@ var execute95 = async (graph, params) => {
23065
23013
  const parsed = schema95.safeParse(params);
23066
23014
  if (!parsed.success)
23067
23015
  return err({ type: "validation_error", message: formatZodError(parsed.error) });
23068
- const { replyToMessageId, bodyContent, subject, replyAll, bodyContentType } = parsed.data;
23016
+ const { replyToMessageId, comment, subject, replyAll, bodyContentType } = parsed.data;
23069
23017
  const action = replyAll === "false" ? "createReply" : "createReplyAll";
23070
23018
  const asHtml = bodyContentType === "HTML";
23071
- if (asHtml && commentCarriesQuoteBoundary(bodyContent)) {
23072
- return err({ type: "validation_error", message: boundaryMarkerRefusal("--body-content") });
23019
+ if (asHtml && commentCarriesQuoteBoundary(comment)) {
23020
+ return err({ type: "validation_error", message: boundaryMarkerRefusal("--comment") });
23073
23021
  }
23074
- const created = await graph.post(`/me/messages/${replyToMessageId}/${action}`, { comment: asHtml ? "" : bodyContent });
23022
+ const created = await graph.post(`/me/messages/${replyToMessageId}/${action}`, { comment: asHtml ? "" : comment });
23075
23023
  if (!created.ok)
23076
23024
  return created;
23077
23025
  if (!isUnsentDraft2(created.value)) {
@@ -23097,10 +23045,10 @@ var execute95 = async (graph, params) => {
23097
23045
  if (draftBody.value.contentType.toLowerCase() !== "html") {
23098
23046
  return err({
23099
23047
  type: "validation_error",
23100
- message: `The thread's draft body is ${draftBody.value.contentType}, not HTML, so HTML cannot be placed above its quoted history without rewriting the quote. Draft ${draftId} was already created - reply to it with \`update-mail-draft --message-id ${draftId} --comment "..."\`, or delete it in Outlook Drafts and retry without --body-content-type HTML.`
23048
+ message: `The thread's draft body is ${draftBody.value.contentType}, not HTML, so HTML cannot be placed above its quoted history without rewriting the quote. Draft ${draftId} was already created - revise it with \`update-mail-draft --message-id ${draftId}\` in comment mode, or delete it in Outlook Drafts and retry without --body-content-type HTML.`
23101
23049
  });
23102
23050
  }
23103
- const spliced = insertCommentAboveQuote(draftBody.value.content, bodyContent);
23051
+ const spliced = insertCommentAboveQuote(draftBody.value.content, comment);
23104
23052
  const patch = { body: { contentType: "HTML", content: spliced.html } };
23105
23053
  if (subject)
23106
23054
  patch.subject = subject;
@@ -23117,21 +23065,20 @@ var meta97 = {
23117
23065
  name: "reply-to-message-id",
23118
23066
  key: "replyToMessageId",
23119
23067
  required: true,
23120
- aliases: [{ name: "id", key: "id" }],
23121
- description: "The message being replied to. Source from list-mail-folder-messages or search-mail-messages. Accepts `--id` as an alias.",
23068
+ description: "The message being replied to. Source from list-mail-folder-messages or search-mail-messages.",
23122
23069
  argumentHint: { kind: "idOrName" }
23123
23070
  },
23124
23071
  {
23125
- name: "body-content",
23126
- key: "bodyContent",
23072
+ name: "comment",
23073
+ key: "comment",
23127
23074
  required: true,
23128
- description: "The reply text, placed above the quoted history. Plain text by default; pass --body-content-type HTML to send it as markup."
23075
+ description: "The reply text, placed above the quoted history. Named for Graph's own createReply payload field, and the same word update-mail-draft uses for the same role. Plain text by default; pass --body-content-type HTML to send it as markup."
23129
23076
  },
23130
23077
  {
23131
23078
  name: "body-content-type",
23132
23079
  key: "bodyContentType",
23133
23080
  required: false,
23134
- description: "Format of --body-content: Text (default) or HTML. Text is handed to Graph as the reply comment, which HTML-escapes it, so markup shows as literal characters. HTML instead creates the draft with an empty comment and splices your markup in at the TOP of the body — above Graph's reply separator (the `<hr>` line) and the quoted thread, so your reply leads the body content — leaving the quoted thread and its styles byte-identical. Rejected when your markup itself contains a quote boundary marker (a pasted reply chain), and when the thread is a plain-text one.",
23081
+ description: "Format of --comment: Text (default) or HTML. Text is handed to Graph as the reply comment, which HTML-escapes it, so markup shows as literal characters. HTML instead creates the draft with an empty comment and splices your markup in at the TOP of the body — above Graph's reply separator (the `<hr>` line) and the quoted thread, so your reply leads the body content — leaving the quoted thread and its styles byte-identical. Rejected when your markup itself contains a quote boundary marker (a pasted reply chain), and when the thread is a plain-text one.",
23135
23082
  argumentHint: { kind: "magicValue", values: ["Text", "HTML"] }
23136
23083
  },
23137
23084
  {
@@ -23148,8 +23095,8 @@ var meta97 = {
23148
23095
  argumentHint: { kind: "magicValue", values: ["true", "false"] }
23149
23096
  }
23150
23097
  ],
23151
- example: 'ask-marcel-office create-reply-draft --reply-to-message-id "AAMkAD..." --body-content "Confirmed for Contoso, aligned with the group choice."',
23152
- bodyTemplate: "Text: POST { comment: '{body-content}' } then optional PATCH { subject?: '{subject}' }. HTML ({body-content-type}): POST { comment: '' } then ONE PATCH { body: { contentType: 'HTML', content: <'{body-content}' spliced at the top of the body, above Graph's <hr> separator and the quote> }, subject?: '{subject}' }",
23098
+ example: 'ask-marcel-office create-reply-draft --reply-to-message-id "AAMkAD..." --comment "Confirmed for Contoso, aligned with the group choice."',
23099
+ bodyTemplate: "Text: POST { comment: '{comment}' } then optional PATCH { subject?: '{subject}' }. HTML ({body-content-type}): POST { comment: '' } then ONE PATCH { body: { contentType: 'HTML', content: <'{comment}' spliced at the top of the body, above Graph's <hr> separator and the quote> }, subject?: '{subject}' }",
23153
23100
  mutates: true,
23154
23101
  scopesRequired: ["Mail.ReadWrite"],
23155
23102
  responseShape: "A confirmation of the write, NOT the whole message: `{ id, subject, toRecipients, ccRecipients, bccRecipients, importance, bodyPreview, isDraft, webLink, conversationId }` (only the fields Graph returned; `{ ok: true }` when Graph answers 204). The `body` is deliberately omitted — you just wrote it, and echoing a long thread's quoted history back cost ~174 KB of context per call. Read the full body with `get-mail-message --id <the returned id>` when you actually need it; `bodyPreview` is Graph's ~255-char summary, enough to confirm WHICH draft answered. The `id` is the draft — refine it with `update-mail-draft`, or open Outlook Drafts to review and send. Dedup caveat: a `conversationId` `$filter` on the Drafts folder is not a reliable 'does a draft already exist on this thread' check. Reply and forward drafts do not always inherit the inbound message's `conversationId` (one thread can split across several), and Graph `$filter` on Drafts is not read-your-writes consistent, so a just-created draft can be missed. To find existing drafts, use the `find-mail-drafts` command, which scans recent drafts and matches client-side on subject and recipients; to revise a draft this session created, reuse the returned `id`."
@@ -23167,6 +23114,7 @@ var schema96 = exports_external.object({
23167
23114
  subject: exports_external.string().optional(),
23168
23115
  bodyContent: exports_external.string().optional(),
23169
23116
  comment: exports_external.string().min(1).optional(),
23117
+ replaceQuotedHistory: exports_external.enum(["true", "false"]).optional(),
23170
23118
  bodyContentType: exports_external.enum(["Text", "HTML"]).optional(),
23171
23119
  toRecipients: exports_external.string().optional(),
23172
23120
  ccRecipients: exports_external.string().optional(),
@@ -23178,6 +23126,10 @@ var noQuoteRefusal = (messageId) => ({
23178
23126
  type: "validation_error",
23179
23127
  message: `Draft ${messageId} has no quoted reply history to preserve, so there is nothing for --comment to sit above. Use --body-content to replace the whole body instead.`
23180
23128
  });
23129
+ var quotedHistoryRefusal = (messageId) => ({
23130
+ type: "validation_error",
23131
+ message: `Draft ${messageId} carries quoted reply history, and --body-content replaces the entire body, quote included. Revise only your own text with --comment, which keeps the quote byte-identical, or pass --replace-quoted-history true to drop the quote deliberately.`
23132
+ });
23181
23133
  var reviseBodyAboveQuote = (draft, messageId, comment, asHtml) => {
23182
23134
  if (draft.contentType.toLowerCase() !== "html") {
23183
23135
  if (asHtml) {
@@ -23212,11 +23164,19 @@ var readDraft = async (graph, messageId) => {
23212
23164
  }
23213
23165
  return ok(parsed.data);
23214
23166
  };
23167
+ var guardQuotedHistory = async (graph, messageId) => {
23168
+ const draft = await readDraft(graph, messageId);
23169
+ if (!draft.ok)
23170
+ return draft;
23171
+ if (!bodyCarriesQuote(draft.value.body.contentType, draft.value.body.content))
23172
+ return ok(undefined);
23173
+ return err(quotedHistoryRefusal(messageId));
23174
+ };
23215
23175
  var execute96 = async (graph, params) => {
23216
23176
  const parsed = schema96.safeParse(params);
23217
23177
  if (!parsed.success)
23218
23178
  return err({ type: "validation_error", message: formatZodError(parsed.error) });
23219
- const { messageId, subject, bodyContent, comment, bodyContentType, toRecipients, ccRecipients, bccRecipients, importance } = parsed.data;
23179
+ const { messageId, subject, bodyContent, comment, replaceQuotedHistory, bodyContentType, toRecipients, ccRecipients, bccRecipients, importance } = parsed.data;
23220
23180
  if ([subject, bodyContent, comment, toRecipients, ccRecipients, bccRecipients, importance].every((v) => v === undefined)) {
23221
23181
  return err({
23222
23182
  type: "validation_error",
@@ -23232,6 +23192,11 @@ var execute96 = async (graph, params) => {
23232
23192
  if (comment !== undefined && bodyContentType === "HTML" && commentCarriesQuoteBoundary(comment)) {
23233
23193
  return err({ type: "validation_error", message: boundaryMarkerRefusal("--comment") });
23234
23194
  }
23195
+ if (bodyContent !== undefined && replaceQuotedHistory !== "true") {
23196
+ const guarded = await guardQuotedHistory(graph, messageId);
23197
+ if (!guarded.ok)
23198
+ return guarded;
23199
+ }
23235
23200
  const body = {};
23236
23201
  if (subject !== undefined)
23237
23202
  body.subject = subject;
@@ -23257,18 +23222,17 @@ var execute96 = async (graph, params) => {
23257
23222
  return slimDraftResult(await graph.patch(`/me/messages/${messageId}`, body));
23258
23223
  };
23259
23224
  var meta98 = {
23260
- summary: "Update an existing mail draft. PATCH /me/messages/{id} — modifies a draft created by create-mail-draft (or any existing draft in the Drafts folder). Only the fields you pass are updated; omitted fields are left unchanged. At least one field must be provided. On a THREADED draft (one made by create-reply-draft / create-forward-draft), revise your text with --comment, which rewrites only what sits above the quoted history and leaves the quote byte-identical; --body-content would replace the whole body and drop the thread. Passing an EMPTY string to a recipient flag clears that list, which is how you drop recipients a reply-all or forward inherited; omitting the flag leaves the list alone. Returns a slim confirmation (id, subject, recipients, importance, bodyPreview, …) - NOT the full body, which you just wrote; read it back with get-mail-message if you need the whole draft before sending.",
23225
+ summary: "Update an existing mail draft. PATCH /me/messages/{id} — modifies a draft created by create-mail-draft (or any existing draft in the Drafts folder). Only the fields you pass are updated; omitted fields are left unchanged. At least one field must be provided. On a THREADED draft (one made by create-reply-draft / create-forward-draft), revise your text with --comment, which rewrites only what sits above the quoted history and leaves the quote byte-identical; --body-content replaces the whole body and would drop the thread, so it is REFUSED on a draft that still carries a quote unless you pass --replace-quoted-history true. Passing an EMPTY string to a recipient flag clears that list, which is how you drop recipients a reply-all or forward inherited; omitting the flag leaves the list alone. Returns a slim confirmation (id, subject, recipients, importance, bodyPreview, …) - NOT the full body, which you just wrote; read it back with get-mail-message if you need the whole draft before sending.",
23261
23226
  category: "mail",
23262
23227
  graphMethod: "PATCH",
23263
- graphPathTemplate: "/me/messages/{message-id} (+ a GET of body,isDraft first when {comment} is used)",
23228
+ graphPathTemplate: "/me/messages/{message-id} (+ a GET of body,isDraft first when {comment} is used, or when {body-content} is used without {replace-quoted-history})",
23264
23229
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/api/message-update",
23265
23230
  options: [
23266
23231
  {
23267
23232
  name: "message-id",
23268
23233
  key: "messageId",
23269
23234
  required: true,
23270
- aliases: [{ name: "id", key: "id" }],
23271
- description: "Draft message ID to update. Source from create-mail-draft response or list-mail-folder-messages --mail-folder-id drafts. Accepts `--id` as an alias.",
23235
+ description: "Draft message ID to update. Source from create-mail-draft response or list-mail-folder-messages --mail-folder-id drafts.",
23272
23236
  argumentHint: { kind: "idOrName" }
23273
23237
  },
23274
23238
  {
@@ -23281,7 +23245,7 @@ var meta98 = {
23281
23245
  name: "body-content",
23282
23246
  key: "bodyContent",
23283
23247
  required: false,
23284
- description: "New email body content. Replaces the ENTIRE body, quoted history included. On a threaded reply or forward draft this is almost never what you want - use --comment to revise only your own text and keep the quote. Pass --body-content-type HTML for rich text. Mutually exclusive with --comment."
23248
+ description: "New email body content. Replaces the ENTIRE body, quoted history included. On a threaded reply or forward draft that is almost never what you want, so the command reads the draft first and REFUSES when it still carries a quote - use --comment to revise only your own text and keep the quote, or pass --replace-quoted-history true to drop it deliberately. Note the sibling commands: create-reply-draft / create-forward-draft name their above-the-quote text --comment; --body-content exists only here. Pass --body-content-type HTML for rich text. Mutually exclusive with --comment."
23285
23249
  },
23286
23250
  {
23287
23251
  name: "comment",
@@ -23289,6 +23253,13 @@ var meta98 = {
23289
23253
  required: false,
23290
23254
  description: "Rewrite ONLY the reply text above the quoted history on a threaded draft, keeping the quote and its styles byte-identical. This is the flag for revising a draft made by create-reply-draft or create-forward-draft; repeated edits replace your text rather than stacking. Refused when the draft has no quoted history (use --body-content), when it is not a draft, and when HTML markup you pass carries a quote boundary marker of its own. Mutually exclusive with --body-content."
23291
23255
  },
23256
+ {
23257
+ name: "replace-quoted-history",
23258
+ key: "replaceQuotedHistory",
23259
+ required: false,
23260
+ description: "Allow --body-content to drop the quoted history on a threaded draft. Without it, --body-content is REFUSED when the draft still carries a quote, because replacing the whole body there silently loses the thread; the refusal points at --comment, which revises only your own text. Pass `true` for the deliberate case: strip the quote but keep the draft threaded on its conversation. Ignored in comment mode, which never touches the quote.",
23261
+ argumentHint: { kind: "magicValue", values: ["true", "false"] }
23262
+ },
23292
23263
  {
23293
23264
  name: "body-content-type",
23294
23265
  key: "bodyContentType",
@@ -23323,7 +23294,7 @@ var meta98 = {
23323
23294
  }
23324
23295
  ],
23325
23296
  example: 'ask-marcel-office update-mail-draft --message-id "AAMkAD..." --subject "Updated: Q3 Report" --to-recipients "alice@example.com,charlie@example.com"',
23326
- 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. With '{comment}': body.content is the draft's own body with the text above the quote replaced, and body.contentType is the draft's own, unchanged",
23297
+ 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. With '{comment}': body.content is the draft's own body with the text above the quote replaced, and body.contentType is the draft's own, unchanged. A '{body-content}' aimed at a draft that still carries a quote costs one GET of body,isDraft and is refused unless '{replace-quoted-history}' is true",
23327
23298
  mutates: true,
23328
23299
  scopesRequired: ["Mail.ReadWrite"],
23329
23300
  responseShape: "A confirmation of the write, NOT the whole message: `{ id, subject, toRecipients, ccRecipients, bccRecipients, importance, bodyPreview, isDraft, webLink, conversationId }` (only the fields Graph returned; `{ ok: true }` when Graph answers 204). The `body` is deliberately omitted — you just wrote it, and echoing a long thread's quoted history back cost ~174 KB of context per call. Read the full body with `get-mail-message --id <the returned id>` when you actually need it; `bodyPreview` is Graph's ~255-char summary, enough to confirm WHICH draft answered. The `id` is the draft — refine it with `update-mail-draft`, or open Outlook Drafts to review and send. Dedup caveat: a `conversationId` `$filter` on the Drafts folder is not a reliable 'does a draft already exist on this thread' check. Reply and forward drafts do not always inherit the inbound message's `conversationId` (one thread can split across several), and Graph `$filter` on Drafts is not read-your-writes consistent, so a just-created draft can be missed. To find existing drafts, use the `find-mail-drafts` command, which scans recent drafts and matches client-side on subject and recipients; to revise a draft this session created, reuse the returned `id`."
@@ -23361,7 +23332,6 @@ var execute97 = async (graph, params) => {
23361
23332
  var meta99 = {
23362
23333
  summary: "Unzip a `.zip` from a OneDrive / SharePoint item and convert every contained file in one call — so \"read the handover archive\" doesn't need a separate unzip + per-file conversion. Office files (docx/xlsx/pptx/odt/ods/odp and their macro-enabled / template variants) are converted to markdown via the local pipelines; plain-text entries (txt/md/csv/json/yaml/…) are decoded inline; legacy OLE .xls (sheetjs) and .doc (word-extractor, text only) are extracted; an Outlook .msg entry is rendered to markdown (headers + body, with its own attachments converted recursively); PDFs have their text layer extracted (text/plain); images, binaries, nested archives, legacy .ppt, and scanned/image-only PDFs (no text layer) are listed with a note (not unpacked) so one unsupported entry never fails the whole archive. Pass `--include-metadata true` to append each Office file's side-channel metadata block. Capped at 100 entries (the archive is buffered in memory); beyond that the response is flagged `truncated`.",
23363
23334
  category: "drive",
23364
- commandAliases: ["convert-drive-item-zip"],
23365
23335
  graphMethod: "GET",
23366
23336
  graphPathTemplate: "/drives/{drive-id}/items/{item-id}/content",
23367
23337
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/api/driveitem-get-content",
@@ -23439,7 +23409,6 @@ var execute98 = async (_graph, _params) => err({
23439
23409
  var meta100 = {
23440
23410
  summary: "Convert a file ON DISK to markdown — the only command that never calls Microsoft Graph (works offline, no login). Runs the same local pipelines as `download-drive-item-as-markdown`: docx (mammoth → turndown), xlsx (sheetjs tables, `--max-cells` OOM cap), pptx (per-slide text), odt/ods/odp, csv, pdf (text layer via unpdf), legacy OLE .xls / .doc, Outlook .msg (headers + body with the quoted reply chain stripped — `--keep-quoted true` restores it — and inline `cid:` images shown as placeholders, attachments converted recursively), plain-text passthrough — and a `.zip` is unpacked with every contained file converted in one call (legacy GBK / CP437 entry names decoded, not mojibaked). What it canNOT do locally: convert TO pdf, and Loop/Fluid/Whiteboard sources — both need a Graph server round-trip (upload to OneDrive and use the drive-item siblings). Pass `--include-metadata true` for the Office side-channel metadata blocks; `--inline-images true` to embed docx images as base64 data URIs.",
23441
23411
  category: "meta",
23442
- commandAliases: ["convert-local-file"],
23443
23412
  graphMethod: "GET",
23444
23413
  graphPathTemplate: "(local) reads {path} from the local filesystem; not a Graph endpoint",
23445
23414
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/",
@@ -23572,7 +23541,6 @@ var execute100 = async (graph, params) => {
23572
23541
  var meta102 = {
23573
23542
  summary: "Unzip a `.zip` Outlook mail attachment and convert every contained file in one call — the mail-side mirror of `convert-drive-item-zip-to-markdown`, so reading a zipped vendor deck doesn't need `get-mail-attachment` + manual `unzip` + per-file conversion. Pulls the fileAttachment bytes, unzips them (legacy GBK / CP437 entry names — Chinese vendor archives written by WinRAR / Windows Explorer — are decoded correctly, not mojibaked), and runs each file through the local pipelines: Office files (docx/xlsx/pptx/odt/ods/odp and macro-enabled / template variants) → markdown; plain-text entries decoded inline; legacy OLE .xls (sheetjs) and .doc (word-extractor, text only) extracted; an inner Outlook .msg rendered; PDFs have their text layer extracted; images, binaries, nested archives, legacy .ppt, and scanned/image-only PDFs are listed with a note (not unpacked) so one unsupported entry never fails the whole archive. Pass `--include-metadata true` to append each Office file's side-channel metadata block. Capped at 100 entries; beyond that the response is flagged `truncated`. itemAttachment / referenceAttachment are rejected (no inline zip payload).",
23574
23543
  category: "mail",
23575
- commandAliases: ["convert-mail-attachment-zip"],
23576
23544
  graphMethod: "GET",
23577
23545
  graphPathTemplate: "/me/messages/{message-id}/attachments/{attachment-id}",
23578
23546
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/api/attachment-get",
@@ -23685,8 +23653,7 @@ var meta104 = {
23685
23653
  name: "message-id",
23686
23654
  key: "messageId",
23687
23655
  required: true,
23688
- aliases: [{ name: "id", key: "id" }],
23689
- description: "Outlook message ID. Returned by `list-mail-messages` or `list-mail-folder-messages`. Accepts `--id` as an alias."
23656
+ description: "Outlook message ID. Returned by `list-mail-messages` or `list-mail-folder-messages`."
23690
23657
  }
23691
23658
  ],
23692
23659
  example: "ask-marcel-office extract-sharepoint-links-in-mail --message-id 'AAMkADk0...'",
@@ -23738,7 +23705,6 @@ var meta106 = {
23738
23705
  name: "chat-id",
23739
23706
  key: "chatId",
23740
23707
  required: true,
23741
- aliases: [{ name: "id", key: "id" }],
23742
23708
  description: "Microsoft Teams chat ID, e.g. `19:abc...@thread.v2`. Returned by `list-chats`."
23743
23709
  },
23744
23710
  ...selectExpandOptions
@@ -23825,7 +23791,6 @@ var meta108 = {
23825
23791
  name: "chat-id",
23826
23792
  key: "chatId",
23827
23793
  required: true,
23828
- aliases: [{ name: "id", key: "id" }],
23829
23794
  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`."
23830
23795
  }
23831
23796
  ],
@@ -23923,7 +23888,6 @@ var meta109 = {
23923
23888
  name: "chat-id",
23924
23889
  key: "chatId",
23925
23890
  required: true,
23926
- aliases: [{ name: "id", key: "id" }],
23927
23891
  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`."
23928
23892
  },
23929
23893
  {
@@ -24640,7 +24604,6 @@ var meta117 = {
24640
24604
  name: "user-id",
24641
24605
  key: "userId",
24642
24606
  required: true,
24643
- aliases: [{ name: "id", key: "id" }],
24644
24607
  description: "Azure AD user ID or userPrincipalName (UPN) — typically the user's email address. Discover via `list-relevant-people` (relevance-ranked colleagues) or `microsoft-search-query --query <name>` (federated person search across the tenant directory)."
24645
24608
  },
24646
24609
  ...odataQueryOptions
@@ -24898,7 +24861,6 @@ var meta127 = {
24898
24861
  name: "team-id",
24899
24862
  key: "teamId",
24900
24863
  required: true,
24901
- aliases: [{ name: "id", key: "id" }],
24902
24864
  description: "Microsoft Teams team ID."
24903
24865
  }
24904
24866
  ],
@@ -24948,7 +24910,6 @@ var meta129 = {
24948
24910
  name: "calendar-group-id",
24949
24911
  key: "calendarGroupId",
24950
24912
  required: true,
24951
- aliases: [{ name: "id", key: "id" }],
24952
24913
  description: "Calendar group ID. Returned by `list-calendar-groups`."
24953
24914
  },
24954
24915
  ...odataQueryOptions
@@ -24998,7 +24959,6 @@ var meta131 = {
24998
24959
  name: "site-id",
24999
24960
  key: "siteId",
25000
24961
  required: true,
25001
- aliases: [{ name: "id", key: "id" }],
25002
24962
  description: "SharePoint site ID. Returned by `search-sharepoint-sites-by-name`."
25003
24963
  },
25004
24964
  ...selectExpandOptions
@@ -25027,7 +24987,6 @@ var meta132 = {
25027
24987
  name: "site-id",
25028
24988
  key: "siteId",
25029
24989
  required: true,
25030
- aliases: [{ name: "id", key: "id" }],
25031
24990
  description: "SharePoint site ID."
25032
24991
  },
25033
24992
  ...noSkipOptions
@@ -25058,7 +25017,6 @@ var meta133 = {
25058
25017
  name: "site-id",
25059
25018
  key: "siteId",
25060
25019
  required: true,
25061
- aliases: [{ name: "id", key: "id" }],
25062
25020
  description: "SharePoint site ID."
25063
25021
  },
25064
25022
  ...noSkipOptions
@@ -25326,15 +25284,15 @@ __export(exports_get_drive_root_delta, {
25326
25284
  meta: () => meta140,
25327
25285
  execute: () => execute138
25328
25286
  });
25329
- var baseSchema67 = exports_external.object({}).strict();
25330
- var { execute: execute138, schema: schema138 } = buildNoSkipListCommand(() => "/me/drive/root/delta()", baseSchema67);
25287
+ var baseSchema67 = exports_external.object({});
25288
+ var { execute: execute138, schema: schema138 } = buildPickODataListCommand(() => "/me/drive/root/delta()", baseSchema67, ["top", "select", "expand"]);
25331
25289
  var meta140 = {
25332
25290
  summary: "Track incremental changes (added / modified / deleted items) anywhere under the signed-in user's OneDrive root. **Takes zero required arguments** — acts implicitly on the signed-in user's primary OneDrive; use `get-drive-delta` to target a specific drive by ID. The first call returns a snapshot plus `@odata.deltaLink`; subsequent calls with that link return only what has changed since. Cross-folder companion to `get-drive-delta` (which scopes to one specific folder).",
25333
25291
  category: "drive",
25334
25292
  graphMethod: "GET",
25335
25293
  graphPathTemplate: "/me/drive/root/delta()",
25336
25294
  graphDocsUrl: "https://learn.microsoft.com/en-us/graph/api/driveitem-delta",
25337
- options: [...noSkipOptions],
25295
+ options: [...pickODataOptions(["top", "select", "expand"])],
25338
25296
  example: "ask-marcel-office get-drive-root-delta",
25339
25297
  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.",
25340
25298
  pagination: true,
@@ -25451,7 +25409,6 @@ var meta144 = {
25451
25409
  name: "site-id",
25452
25410
  key: "siteId",
25453
25411
  required: true,
25454
- aliases: [{ name: "id", key: "id" }],
25455
25412
  description: "SharePoint site ID."
25456
25413
  }
25457
25414
  ],
@@ -25491,8 +25448,7 @@ var meta145 = {
25491
25448
  name: "list-item-id",
25492
25449
  key: "listItemId",
25493
25450
  required: true,
25494
- description: "List item ID inside the list. Returned by `list-sharepoint-site-list-items`.",
25495
- aliases: [{ name: "item-id", key: "itemId" }]
25451
+ description: "List item ID inside the list. Returned by `list-sharepoint-site-list-items`."
25496
25452
  },
25497
25453
  ...noSkipOptions
25498
25454
  ],
@@ -25528,11 +25484,7 @@ var meta146 = {
25528
25484
  name: "message-rule-id",
25529
25485
  key: "messageRuleId",
25530
25486
  required: true,
25531
- description: "Message rule ID. Returned by `list-mail-rules`.",
25532
- aliases: [
25533
- { name: "id", key: "id" },
25534
- { name: "rule-id", key: "ruleId" }
25535
- ]
25487
+ description: "Message rule ID. Returned by `list-mail-rules`."
25536
25488
  }
25537
25489
  ],
25538
25490
  example: "ask-marcel-office get-mail-rule --message-rule-id 'AQAAANC...'",
@@ -25682,7 +25634,6 @@ var meta151 = {
25682
25634
  name: "team-id",
25683
25635
  key: "teamId",
25684
25636
  required: true,
25685
- aliases: [{ name: "id", key: "id" }],
25686
25637
  description: "Microsoft Teams team ID. Returned by `list-joined-teams`."
25687
25638
  },
25688
25639
  ...selectExpandOptions
@@ -25711,12 +25662,7 @@ var meta152 = {
25711
25662
  name: "todo-task-list-id",
25712
25663
  key: "todoTaskListId",
25713
25664
  required: true,
25714
- description: "Microsoft To Do task list ID. Returned by `list-todo-task-lists`.",
25715
- aliases: [
25716
- { name: "id", key: "id" },
25717
- { name: "task-list-id", key: "taskListId" },
25718
- { name: "todo-list-id", key: "todoListId" }
25719
- ]
25665
+ description: "Microsoft To Do task list ID. Returned by `list-todo-task-lists`."
25720
25666
  }
25721
25667
  ],
25722
25668
  example: "ask-marcel-office list-todo-tasks-delta --todo-task-list-id 'AAMkAD...'",
@@ -25840,7 +25786,6 @@ var meta155 = {
25840
25786
  name: "user-id",
25841
25787
  key: "userId",
25842
25788
  required: true,
25843
- aliases: [{ name: "id", key: "id" }],
25844
25789
  description: "Azure AD user ID, UPN, or email (returns the full profile via the elevated token), OR a display name (returns relevant-people candidates on the basic token). Discover ids via `list-relevant-people` or `microsoft-search-query`."
25845
25790
  },
25846
25791
  ...selectExpandOptions
@@ -25882,7 +25827,6 @@ var meta156 = {
25882
25827
  name: "user-id",
25883
25828
  key: "userId",
25884
25829
  required: true,
25885
- aliases: [{ name: "id", key: "id" }],
25886
25830
  description: "Azure AD user ID or UPN — typically the user's email address. Discover via `list-relevant-people` (relevance-ranked colleagues) or `microsoft-search-query --query <name>` (federated person search across the tenant directory)."
25887
25831
  },
25888
25832
  ...selectExpandOptions
@@ -25954,7 +25898,6 @@ var meta159 = {
25954
25898
  name: "group-id",
25955
25899
  key: "groupId",
25956
25900
  required: true,
25957
- aliases: [{ name: "id", key: "id" }],
25958
25901
  description: "Azure AD group object ID. Use `list-groups` to find one."
25959
25902
  },
25960
25903
  ...selectExpandOptions
@@ -25983,7 +25926,6 @@ var meta160 = {
25983
25926
  name: "group-id",
25984
25927
  key: "groupId",
25985
25928
  required: true,
25986
- aliases: [{ name: "id", key: "id" }],
25987
25929
  description: "Azure AD group object ID. Use `list-groups` to find one."
25988
25930
  },
25989
25931
  ...odataQueryOptions
@@ -26013,7 +25955,6 @@ var meta161 = {
26013
25955
  name: "group-id",
26014
25956
  key: "groupId",
26015
25957
  required: true,
26016
- aliases: [{ name: "id", key: "id" }],
26017
25958
  description: "Azure AD group object ID. Use `list-groups` to find one."
26018
25959
  },
26019
25960
  ...odataQueryOptions
@@ -26043,7 +25984,6 @@ var meta162 = {
26043
25984
  name: "group-id",
26044
25985
  key: "groupId",
26045
25986
  required: true,
26046
- aliases: [{ name: "id", key: "id" }],
26047
25987
  description: "Azure AD group object ID for a unified (Microsoft 365) group. Use `list-groups` to find one."
26048
25988
  },
26049
25989
  ...odataQueryOptions
@@ -26073,17 +26013,15 @@ var meta163 = {
26073
26013
  name: "group-id",
26074
26014
  key: "groupId",
26075
26015
  required: true,
26076
- aliases: [{ name: "id", key: "id" }],
26077
26016
  description: "Azure AD group object ID for a unified (Microsoft 365) group."
26078
26017
  },
26079
26018
  {
26080
26019
  name: "start-date-time",
26081
26020
  key: "startDateTime",
26082
26021
  required: true,
26083
- aliases: [{ name: "start", key: "start" }],
26084
26022
  description: `Start of the window (recurrences are expanded across it). ${RELATIVE_DATE_DESCRIPTION}`
26085
26023
  },
26086
- { name: "end-date-time", key: "endDateTime", required: true, aliases: [{ name: "end", key: "end" }], description: `End of the window. ${RELATIVE_DATE_DESCRIPTION}` },
26024
+ { name: "end-date-time", key: "endDateTime", required: true, description: `End of the window. ${RELATIVE_DATE_DESCRIPTION}` },
26087
26025
  ...odataQueryOptions
26088
26026
  ],
26089
26027
  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'",
@@ -26111,7 +26049,6 @@ var meta164 = {
26111
26049
  name: "group-id",
26112
26050
  key: "groupId",
26113
26051
  required: true,
26114
- aliases: [{ name: "id", key: "id" }],
26115
26052
  description: "Azure AD group object ID for a unified (Microsoft 365) group."
26116
26053
  },
26117
26054
  ...odataQueryOptions
@@ -26141,7 +26078,6 @@ var meta165 = {
26141
26078
  name: "group-id",
26142
26079
  key: "groupId",
26143
26080
  required: true,
26144
- aliases: [{ name: "id", key: "id" }],
26145
26081
  description: "Azure AD group object ID for a unified (Microsoft 365) group."
26146
26082
  },
26147
26083
  ...odataQueryOptions
@@ -26176,8 +26112,7 @@ var meta166 = {
26176
26112
  name: "message-id",
26177
26113
  key: "messageId",
26178
26114
  required: true,
26179
- aliases: [{ name: "id", key: "id" }],
26180
- description: "Outlook message ID. Returned by `list-mail-messages` or `search-mail-messages`. Accepts `--id` as an alias."
26115
+ description: "Outlook message ID. Returned by `list-mail-messages` or `search-mail-messages`."
26181
26116
  }
26182
26117
  ],
26183
26118
  example: "ask-marcel-office get-mail-message-mime --message-id 'AAMkAD...'",
@@ -26192,10 +26127,19 @@ __export(exports_list_mail_folder_messages_delta, {
26192
26127
  meta: () => meta167,
26193
26128
  execute: () => execute165
26194
26129
  });
26195
- var baseSchema87 = exports_external.object({ mailFolderId: exports_external.string().min(1) });
26196
- var { execute: execute165, schema: schema165 } = buildListCommand((p) => `/me/mailFolders/${p.mailFolderId}/messages/delta()`, baseSchema87);
26130
+ var schema165 = exports_external.object({ mailFolderId: exports_external.string().min(1) }).extend(pickODataShape(["top", "select", "filter", "expand"]));
26131
+ var execute165 = async (graph, params) => {
26132
+ const parsed = schema165.safeParse(params);
26133
+ if (!parsed.success)
26134
+ return err({ type: "validation_error", message: formatZodError(parsed.error) });
26135
+ const { mailFolderId, top, ...odata } = parsed.data;
26136
+ const headers = {};
26137
+ if (top !== undefined)
26138
+ headers["Prefer"] = `odata.maxpagesize=${top}`;
26139
+ return graph.get(appendOData(`/me/mailFolders/${mailFolderId}/messages/delta()`, odata), headers);
26140
+ };
26197
26141
  var meta167 = {
26198
- summary: "Track incremental changes (added / updated / deleted messages) within a single mail folder using Microsoft Graph delta tokens. The first call returns the current snapshot plus a `@odata.deltaLink`; subsequent calls with that link return only what has changed since.",
26142
+ summary: 'Track incremental changes (added / updated / deleted messages) within a single mail folder using Microsoft Graph delta tokens. The first call returns the current snapshot plus a `@odata.deltaLink`; subsequent calls with that link return only what has changed since. `--top` is translated into the `Prefer: odata.maxpagesize=N` header: as a `$top` query parameter Graph reads a satisfied count as "sync complete" and hands back a deltaLink after N items, silently abandoning the rest of the folder. `$skip` and `$orderby` are NOT exposed — Graph ignores the former on this endpoint and rejects the latter unless it merely restates the default `receivedDateTime desc`.',
26199
26143
  category: "mail",
26200
26144
  graphMethod: "GET",
26201
26145
  graphPathTemplate: "/me/mailFolders/{mail-folder-id}/messages/delta()",
@@ -26205,15 +26149,14 @@ var meta167 = {
26205
26149
  name: "mail-folder-id",
26206
26150
  key: "mailFolderId",
26207
26151
  required: true,
26208
- aliases: [{ name: "id", key: "id" }],
26209
26152
  description: "Mail folder ID or well-known name (`inbox`, `archive`, `sentitems`, `deleteditems`, `junkemail`, `drafts`). Returned by `list-mail-folders`."
26210
26153
  },
26211
- ...odataQueryOptions
26154
+ ...pickODataOptions(["top", "select", "filter", "expand"])
26212
26155
  ],
26213
26156
  example: "ask-marcel-office list-mail-folder-messages-delta --mail-folder-id 'inbox'",
26214
- 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`).",
26157
+ 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`). A `deltaLink` on the FIRST page means the folder is fully synced, not that it was truncated.",
26215
26158
  pagination: true,
26216
- paginationStrategy: "deltaLink"
26159
+ paginationStrategy: "preferMaxPageSize"
26217
26160
  };
26218
26161
 
26219
26162
  // src/use-cases/commands/list-shared-mailbox-messages.ts
@@ -26223,8 +26166,8 @@ __export(exports_list_shared_mailbox_messages, {
26223
26166
  meta: () => meta168,
26224
26167
  execute: () => execute166
26225
26168
  });
26226
- var baseSchema88 = exports_external.object({ userId: exports_external.string().min(1) });
26227
- var { execute: execute166, schema: schema166 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/messages`, baseSchema88);
26169
+ var baseSchema87 = exports_external.object({ userId: exports_external.string().min(1) });
26170
+ var { execute: execute166, schema: schema166 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/messages`, baseSchema87);
26228
26171
  var meta168 = {
26229
26172
  summary: "List messages from a shared or delegated mailbox the signed-in user has read access to. Same shape as `list-mail-messages` but scoped to a specific mailbox owner. 403 if the signed-in user does not have shared access to that mailbox.",
26230
26173
  category: "mail",
@@ -26236,7 +26179,6 @@ var meta168 = {
26236
26179
  name: "user-id",
26237
26180
  key: "userId",
26238
26181
  required: true,
26239
- aliases: [{ name: "id", key: "id" }],
26240
26182
  description: "Azure AD user ID or UPN of the shared mailbox or delegated user. The signed-in user must have `Mail.Read.Shared` access (granted by the mailbox owner)."
26241
26183
  },
26242
26184
  ...odataQueryOptions
@@ -26253,8 +26195,8 @@ __export(exports_list_shared_mailbox_folder_messages, {
26253
26195
  meta: () => meta169,
26254
26196
  execute: () => execute167
26255
26197
  });
26256
- var baseSchema89 = exports_external.object({ userId: exports_external.string().min(1), mailFolderId: exports_external.string().min(1) });
26257
- var { execute: execute167, schema: schema167 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/mailFolders/${p.mailFolderId}/messages`, baseSchema89);
26198
+ var baseSchema88 = exports_external.object({ userId: exports_external.string().min(1), mailFolderId: exports_external.string().min(1) });
26199
+ var { execute: execute167, schema: schema167 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/mailFolders/${p.mailFolderId}/messages`, baseSchema88);
26258
26200
  var meta169 = {
26259
26201
  summary: "List messages in a single folder of a shared / delegated mailbox.",
26260
26202
  category: "mail",
@@ -26288,8 +26230,8 @@ __export(exports_get_shared_mailbox_message, {
26288
26230
  meta: () => meta170,
26289
26231
  execute: () => execute168
26290
26232
  });
26291
- var baseSchema90 = exports_external.object({ userId: exports_external.string().min(1), messageId: exports_external.string().min(1) });
26292
- var { execute: execute168, schema: schema168 } = buildSelectableCommand((p) => `/users/${encodeURIComponent(p.userId)}/messages/${p.messageId}`, baseSchema90);
26233
+ var baseSchema89 = exports_external.object({ userId: exports_external.string().min(1), messageId: exports_external.string().min(1) });
26234
+ var { execute: execute168, schema: schema168 } = buildSelectableCommand((p) => `/users/${encodeURIComponent(p.userId)}/messages/${p.messageId}`, baseSchema89);
26293
26235
  var meta170 = {
26294
26236
  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.",
26295
26237
  category: "mail",
@@ -26343,7 +26285,6 @@ var meta171 = {
26343
26285
  name: "conversation-id",
26344
26286
  key: "conversationId",
26345
26287
  required: true,
26346
- aliases: [{ name: "id", key: "id" }],
26347
26288
  description: "Outlook `conversationId` of any message in the thread (returned by every mail-listing command and by `get-mail-message`)."
26348
26289
  },
26349
26290
  ...allowedOptions
@@ -26360,8 +26301,8 @@ __export(exports_list_focused_inbox_overrides, {
26360
26301
  meta: () => meta172,
26361
26302
  execute: () => execute170
26362
26303
  });
26363
- var baseSchema91 = exports_external.object({}).strict();
26364
- var { execute: execute170, schema: schema170 } = buildListCommand(() => "/me/inferenceClassification/overrides", baseSchema91);
26304
+ var baseSchema90 = exports_external.object({}).strict();
26305
+ var { execute: execute170, schema: schema170 } = buildListCommand(() => "/me/inferenceClassification/overrides", baseSchema90);
26365
26306
  var meta172 = {
26366
26307
  summary: "List the signed-in user's Focused Inbox classification overrides — sender addresses they've manually moved to Focused or Other, which override Microsoft's automatic classifier.",
26367
26308
  category: "mail",
@@ -26401,8 +26342,8 @@ __export(exports_list_shared_calendar_events, {
26401
26342
  meta: () => meta174,
26402
26343
  execute: () => execute172
26403
26344
  });
26404
- var baseSchema92 = exports_external.object({ userId: exports_external.string().min(1) });
26405
- var { execute: execute172, schema: schema172 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/calendar/events`, baseSchema92);
26345
+ var baseSchema91 = exports_external.object({ userId: exports_external.string().min(1) });
26346
+ var { execute: execute172, schema: schema172 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/calendar/events`, baseSchema91);
26406
26347
  var meta174 = {
26407
26348
  summary: "List events from another user's primary calendar (shared / delegated access). 403 without `Calendars.Read.Shared`.",
26408
26349
  category: "calendar",
@@ -26414,7 +26355,6 @@ var meta174 = {
26414
26355
  name: "user-id",
26415
26356
  key: "userId",
26416
26357
  required: true,
26417
- aliases: [{ name: "id", key: "id" }],
26418
26358
  description: "Azure AD user ID or UPN whose calendar to read. Requires `Calendars.Read.Shared` access (granted by the calendar owner)."
26419
26359
  },
26420
26360
  ...odataQueryOptions
@@ -26431,8 +26371,8 @@ __export(exports_get_shared_calendar_view, {
26431
26371
  meta: () => meta175,
26432
26372
  execute: () => execute173
26433
26373
  });
26434
- var baseSchema93 = exports_external.object({ userId: exports_external.string().min(1), startDateTime: isoDateTimeField, endDateTime: isoDateTimeField });
26435
- var { execute: execute173, schema: schema173 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/calendarView?startDateTime=${encodeURIComponent(p.startDateTime)}&endDateTime=${encodeURIComponent(p.endDateTime)}`, baseSchema93);
26374
+ var baseSchema92 = exports_external.object({ userId: exports_external.string().min(1), startDateTime: isoDateTimeField, endDateTime: isoDateTimeField });
26375
+ var { execute: execute173, schema: schema173 } = buildListCommand((p) => `/users/${encodeURIComponent(p.userId)}/calendarView?startDateTime=${encodeURIComponent(p.startDateTime)}&endDateTime=${encodeURIComponent(p.endDateTime)}`, baseSchema92);
26436
26376
  var meta175 = {
26437
26377
  summary: "Return a date-windowed calendar view from another user's primary calendar (shared / delegated access). Recurrences expanded into individual occurrences.",
26438
26378
  category: "calendar",
@@ -26444,11 +26384,10 @@ var meta175 = {
26444
26384
  name: "user-id",
26445
26385
  key: "userId",
26446
26386
  required: true,
26447
- aliases: [{ name: "id", key: "id" }],
26448
26387
  description: "Azure AD user ID or UPN of the calendar owner."
26449
26388
  },
26450
- { name: "start-date-time", key: "startDateTime", required: true, aliases: [{ name: "start", key: "start" }], description: `Start of the window. ${RELATIVE_DATE_DESCRIPTION}` },
26451
- { name: "end-date-time", key: "endDateTime", required: true, aliases: [{ name: "end", key: "end" }], description: `End of the window. ${RELATIVE_DATE_DESCRIPTION}` },
26389
+ { name: "start-date-time", key: "startDateTime", required: true, description: `Start of the window. ${RELATIVE_DATE_DESCRIPTION}` },
26390
+ { name: "end-date-time", key: "endDateTime", required: true, description: `End of the window. ${RELATIVE_DATE_DESCRIPTION}` },
26452
26391
  ...odataQueryOptions
26453
26392
  ],
26454
26393
  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'",
@@ -26463,8 +26402,8 @@ __export(exports_list_sharepoint_list_columns, {
26463
26402
  meta: () => meta176,
26464
26403
  execute: () => execute174
26465
26404
  });
26466
- var baseSchema94 = exports_external.object({ siteId: exports_external.string().min(1), listId: exports_external.string().min(1) });
26467
- var { execute: execute174, schema: schema174 } = buildSelectableCommand((p) => `/sites/${p.siteId}/lists/${p.listId}/columns`, baseSchema94);
26405
+ var baseSchema93 = exports_external.object({ siteId: exports_external.string().min(1), listId: exports_external.string().min(1) });
26406
+ var { execute: execute174, schema: schema174 } = buildSelectableCommand((p) => `/sites/${p.siteId}/lists/${p.listId}/columns`, baseSchema93);
26468
26407
  var meta176 = {
26469
26408
  summary: "List the column definitions (schema) of a SharePoint list. Useful before reading list items so you know which fields exist and their types. Note: Graph silently ignores `$top` and `$skip` on this endpoint, so the CLI exposes only `--select` and `--expand`.",
26470
26409
  category: "sharepoint",
@@ -26497,8 +26436,8 @@ __export(exports_get_sharepoint_list_column, {
26497
26436
  meta: () => meta177,
26498
26437
  execute: () => execute175
26499
26438
  });
26500
- var baseSchema95 = exports_external.object({ siteId: exports_external.string().min(1), listId: exports_external.string().min(1), columnId: exports_external.string().min(1) });
26501
- var { execute: execute175, schema: schema175 } = buildSelectableCommand((p) => `/sites/${p.siteId}/lists/${p.listId}/columns/${p.columnId}`, baseSchema95);
26439
+ var baseSchema94 = exports_external.object({ siteId: exports_external.string().min(1), listId: exports_external.string().min(1), columnId: exports_external.string().min(1) });
26440
+ var { execute: execute175, schema: schema175 } = buildSelectableCommand((p) => `/sites/${p.siteId}/lists/${p.listId}/columns/${p.columnId}`, baseSchema94);
26502
26441
  var meta177 = {
26503
26442
  summary: "Return a single column definition from a SharePoint list.",
26504
26443
  category: "sharepoint",
@@ -26557,8 +26496,8 @@ var wrapOnenote5kLimit = (inner14) => async (graph, params) => {
26557
26496
  };
26558
26497
 
26559
26498
  // src/use-cases/commands/list-sharepoint-site-onenote-notebooks.ts
26560
- var baseSchema96 = exports_external.object({ siteId: exports_external.string().min(1) });
26561
- var inner14 = buildListCommand((p) => `/sites/${p.siteId}/onenote/notebooks`, baseSchema96);
26499
+ var baseSchema95 = exports_external.object({ siteId: exports_external.string().min(1) });
26500
+ var inner14 = buildListCommand((p) => `/sites/${p.siteId}/onenote/notebooks`, baseSchema95);
26562
26501
  var execute176 = wrapOnenote5kLimit(inner14.execute);
26563
26502
  var { schema: schema176 } = inner14;
26564
26503
  var meta178 = {
@@ -26572,7 +26511,6 @@ var meta178 = {
26572
26511
  name: "site-id",
26573
26512
  key: "siteId",
26574
26513
  required: true,
26575
- aliases: [{ name: "id", key: "id" }],
26576
26514
  description: "SharePoint site ID."
26577
26515
  },
26578
26516
  ...odataQueryOptions
@@ -26589,8 +26527,8 @@ __export(exports_list_sharepoint_site_onenote_notebook_sections, {
26589
26527
  meta: () => meta179,
26590
26528
  execute: () => execute177
26591
26529
  });
26592
- var baseSchema97 = exports_external.object({ siteId: exports_external.string().min(1), notebookId: exports_external.string().min(1) });
26593
- var inner15 = buildListCommand((p) => `/sites/${p.siteId}/onenote/notebooks/${p.notebookId}/sections`, baseSchema97);
26530
+ var baseSchema96 = exports_external.object({ siteId: exports_external.string().min(1), notebookId: exports_external.string().min(1) });
26531
+ var inner15 = buildListCommand((p) => `/sites/${p.siteId}/onenote/notebooks/${p.notebookId}/sections`, baseSchema96);
26594
26532
  var execute177 = wrapOnenote5kLimit(inner15.execute);
26595
26533
  var { schema: schema177 } = inner15;
26596
26534
  var meta179 = {
@@ -26626,8 +26564,8 @@ __export(exports_list_sharepoint_site_onenote_section_pages, {
26626
26564
  meta: () => meta180,
26627
26565
  execute: () => execute178
26628
26566
  });
26629
- var baseSchema98 = exports_external.object({ siteId: exports_external.string().min(1), onenoteSectionId: exports_external.string().min(1) });
26630
- var inner16 = buildListCommand((p) => `/sites/${p.siteId}/onenote/sections/${p.onenoteSectionId}/pages`, baseSchema98);
26567
+ var baseSchema97 = exports_external.object({ siteId: exports_external.string().min(1), onenoteSectionId: exports_external.string().min(1) });
26568
+ var inner16 = buildListCommand((p) => `/sites/${p.siteId}/onenote/sections/${p.onenoteSectionId}/pages`, baseSchema97);
26631
26569
  var execute178 = wrapOnenote5kLimit(inner16.execute);
26632
26570
  var { schema: schema178 } = inner16;
26633
26571
  var meta180 = {
@@ -26647,8 +26585,7 @@ var meta180 = {
26647
26585
  name: "onenote-section-id",
26648
26586
  key: "onenoteSectionId",
26649
26587
  required: true,
26650
- description: "OneNote section ID inside the site.",
26651
- aliases: [{ name: "section-id", key: "sectionId" }]
26588
+ description: "OneNote section ID inside the site."
26652
26589
  },
26653
26590
  ...odataQueryOptions
26654
26591
  ],
@@ -26689,8 +26626,7 @@ var meta181 = {
26689
26626
  name: "onenote-page-id",
26690
26627
  key: "onenotePageId",
26691
26628
  required: true,
26692
- description: "OneNote page ID inside the site.",
26693
- aliases: [{ name: "page-id", key: "pageId" }]
26629
+ description: "OneNote page ID inside the site."
26694
26630
  }
26695
26631
  ],
26696
26632
  example: "ask-marcel-office get-sharepoint-site-onenote-page-content --site-id 'contoso.sharepoint.com,...' --onenote-page-id 'p1'",
@@ -26705,8 +26641,8 @@ __export(exports_list_drive_item_thumbnails, {
26705
26641
  meta: () => meta182,
26706
26642
  execute: () => execute180
26707
26643
  });
26708
- var baseSchema99 = exports_external.object({ driveId: exports_external.string().min(1), itemId: exports_external.string().min(1), ...tenantIdShape });
26709
- var { execute: execute180, schema: schema180 } = buildNoSkipListCommand((p) => `/drives/${p.driveId}/items/${p.itemId}/thumbnails`, baseSchema99);
26644
+ var baseSchema98 = exports_external.object({ driveId: exports_external.string().min(1), itemId: exports_external.string().min(1), ...tenantIdShape });
26645
+ var { execute: execute180, schema: schema180 } = buildNoSkipListCommand((p) => `/drives/${p.driveId}/items/${p.itemId}/thumbnails`, baseSchema98);
26710
26646
  var meta182 = {
26711
26647
  summary: "List thumbnail URLs (small / medium / large) for a OneDrive / SharePoint file. Each thumbnail set has pre-signed CDN URLs you can render in a UI without further auth.",
26712
26648
  category: "drive",
@@ -26836,8 +26772,8 @@ __export(exports_list_rooms, {
26836
26772
  meta: () => meta184,
26837
26773
  execute: () => execute182
26838
26774
  });
26839
- var baseSchema100 = exports_external.object({}).strict();
26840
- var { execute: execute182, schema: schema182 } = buildListCommand(() => "/places/microsoft.graph.room", baseSchema100);
26775
+ var baseSchema99 = exports_external.object({}).strict();
26776
+ var { execute: execute182, schema: schema182 } = buildListCommand(() => "/places/microsoft.graph.room", baseSchema99);
26841
26777
  var meta184 = {
26842
26778
  summary: "List bookable meeting rooms in the tenant. Each `room` has `displayName`, `emailAddress`, `capacity`, `building`, `floorNumber`, and `isWheelChairAccessible`. Use the `emailAddress` as a meeting `attendee` for room booking. Pass `--top 5` to limit the response — large tenants return tens of KB by default.",
26843
26779
  category: "calendar",
@@ -26857,8 +26793,8 @@ __export(exports_list_room_lists, {
26857
26793
  meta: () => meta185,
26858
26794
  execute: () => execute183
26859
26795
  });
26860
- var baseSchema101 = exports_external.object({}).strict();
26861
- var { execute: execute183, schema: schema183 } = buildListCommand(() => "/places/microsoft.graph.roomList", baseSchema101);
26796
+ var baseSchema100 = exports_external.object({}).strict();
26797
+ var { execute: execute183, schema: schema183 } = buildListCommand(() => "/places/microsoft.graph.roomList", baseSchema100);
26862
26798
  var meta185 = {
26863
26799
  summary: "List room lists — usually one per building. Use these to scope a room search by location: a roomList groups the rooms in one office, then `/places/{roomList}/rooms` lists just those rooms. Pass `--top N` to limit the response on large tenants.",
26864
26800
  category: "calendar",
@@ -26878,8 +26814,8 @@ __export(exports_list_trending_insights, {
26878
26814
  meta: () => meta186,
26879
26815
  execute: () => execute184
26880
26816
  });
26881
- var baseSchema102 = exports_external.object({}).strict();
26882
- var { execute: execute184, schema: schema184 } = buildListCommand(() => "/me/insights/trending", baseSchema102);
26817
+ var baseSchema101 = exports_external.object({}).strict();
26818
+ var { execute: execute184, schema: schema184 } = buildListCommand(() => "/me/insights/trending", baseSchema101);
26883
26819
  var meta186 = {
26884
26820
  summary: "List documents trending around the signed-in user — files popular in their working network (colleagues' recent edits, shares, opens). Microsoft's relevance ranking, useful for surfacing unfamiliar but related work.",
26885
26821
  category: "drive",
@@ -26893,7 +26829,7 @@ var meta186 = {
26893
26829
  };
26894
26830
 
26895
26831
  // src/use-cases/commands/index.ts
26896
- var commands = {
26832
+ var modules = {
26897
26833
  "list-drives": exports_list_drives,
26898
26834
  "get-drive-root-item": exports_get_drive_root_item,
26899
26835
  "list-folder-files": exports_list_folder_files,
@@ -27079,6 +27015,7 @@ var commands = {
27079
27015
  "list-todo-tasks-delta": exports_list_todo_tasks_delta,
27080
27016
  "next-page": exports_next_page
27081
27017
  };
27018
+ var commands = Object.fromEntries(Object.entries(modules).map(([name, command]) => [name, withUnknownParamRejection(command)]));
27082
27019
  // src/composition/build-deps.ts
27083
27020
  import { join as join2 } from "node:path";
27084
27021
  var defaultCachePath = (home) => join2(home, ".ask-marcel", "token-cache.json");