ask-marcel-office-cli 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,72 @@
2
2
 
3
3
  All notable changes to `ask-marcel-office-cli` are documented here.
4
4
 
5
+ ## 2.1.0
6
+
7
+ ### Added
8
+
9
+ - **`create-forward-draft`** creates an UNSENT forward draft of an existing
10
+ message. `POST /me/messages/{id}/createForward` mints the draft (`FW:` subject,
11
+ quoted original) with your comment placed above the quote and the recipients
12
+ set, in one call (`Mail.ReadWrite`, already on the basic token).
13
+ `--to-recipients` is required (a forward with no recipient is not actionable);
14
+ `--cc-recipients` and a `--subject` override are optional. Like the other
15
+ mail-draft commands, it produces an UNSENT draft only; the CLI can never send.
16
+ This is the fourth and last write command, closing the "forward to the right
17
+ owner" gap that `create-reply-draft` (in-thread) could not.
18
+ - **`convert-local-file --include-images`** (a `.zip` only) also extracts every
19
+ archive entry's embedded images (docx/xlsx/pptx OOXML media parts, pdf page
20
+ images), so a screenshot pasted inside a zipped document is reachable in one
21
+ call.
22
+ - **`login` now reports all four cached tokens** (basic, elevated/M365, and the
23
+ two Teams-chat substrate tokens chatsvcagg / ic3) with each one's time-left and
24
+ refresh route, so running `login` while already signed in shows the full token
25
+ picture instead of a bare `{ status: "authenticated" }`. Each token is
26
+ `{ available, expiresInSeconds?, refresh: "automatic" | "interactive", reason? }`:
27
+ basic/chatsvcagg/ic3 refresh automatically from the cached refresh token; the
28
+ elevated token is `interactive` (re-captured only on a browser login).
29
+ - **`login --force`** ignores the cache and re-captures every token via the
30
+ browser in one pass — the only way to refresh the elevated token while the
31
+ basic token is still valid. The persistent browser profile is reused, so you
32
+ are usually not re-prompted for credentials.
33
+ - **`scopes-check` now reports the elevated (M365ChatClient) token** plus the two
34
+ Teams-chat substrate tokens (`chatsvcagg` / `ic3`), each in an
35
+ `{ available, expiresInSeconds? }` block, so a fresh process can pre-flight the
36
+ historical-version download / convert commands instead of discovering a 403
37
+ mid-run. The two substrate blocks are additive; the existing top-level fields
38
+ are unchanged.
39
+ - **Machine-readable `errorCode`s on more error paths** — the elevated /
40
+ substrate fail-fast (`secondary_token_unavailable`) and the client-side
41
+ unsupported-input rejections (`unsupported_image` / `unsupported_format` /
42
+ `unsupported_legacy_office` / `unsupported_document`), so an agent branches on
43
+ a stable code instead of substring-matching the message.
44
+
45
+ ### Fixed
46
+
47
+ - **`create-forward-draft` and `create-reply-draft` no longer drop the forwarded
48
+ / quoted body.** They set the comment via Graph's `comment` parameter on the
49
+ `createForward` / `createReplyAll` POST, which places it above the preserved
50
+ quote. The previous implementation PATCHed `body` with only the comment, which
51
+ **replaced** the whole draft body and dropped the entire forwarded original (a
52
+ forward went out with just the comment, no message). Caught by a live smoke
53
+ test; the fix is live-verified.
54
+
55
+ ### Changed
56
+
57
+ - The `parseRecipients` helper shared by the mail-draft write commands moved to
58
+ `parse-recipients.ts` (one definition, three call sites), with no behaviour
59
+ change.
60
+ - `scopes-check` `responseShape` corrected: `elevated.expiresInSeconds` is
61
+ omitted (the key is absent) when no elevated token is cached, not `null`.
62
+
63
+ ### Removed
64
+
65
+ - The `--body-content-type` flag on **`create-forward-draft` and
66
+ `create-reply-draft`** is removed. It never affected the quoted body (Graph
67
+ embeds the comment / reply as text above the quote), so it was a no-op on those
68
+ two commands. It remains on `create-mail-draft` and `update-mail-draft`, which
69
+ set the body directly.
70
+
5
71
  ## 2.0.0
6
72
 
7
73
  Breaking auth simplification, a repo-wide privacy scrub (including a rewrite of
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ask-marcel-office-cli
2
2
 
3
- **A Microsoft Graph CLI built for LLMs.** 179 commands across Mail, Calendar, OneDrive, SharePoint, Excel, Teams chats, Planner / To-Do, OneNote, and directory — plus local-file tools (markdown conversion, image extraction) that need no sign-in at all. Sign in once with your Microsoft 365 account — no Azure app registration, no admin consent, no client secrets.
3
+ **A Microsoft Graph CLI built for LLMs.** 180 commands across Mail, Calendar, OneDrive, SharePoint, Excel, Teams chats, Planner / To-Do, OneNote, and directory — plus local-file tools (markdown conversion, image extraction) that need no sign-in at all. Sign in once with your Microsoft 365 account — no Azure app registration, no admin consent, no client secrets.
4
4
 
5
5
  ```bash
6
6
  npm i -g ask-marcel-office-cli
@@ -25,7 +25,7 @@ LLM tool-loops keep hitting the same three walls with Microsoft Graph:
25
25
 
26
26
  ### Read-only by design
27
27
 
28
- **This is the most important property.** 173 GET endpoints + 3 read-only POST (two searches + free/busy lookup) + 2 POST (create mail draft / create threaded reply draft) + 1 PATCH (update draft) = 179 commands. No `send-mail`, no `create-event`, no `upload-file`, no `delete-anything`. The only write operations are draft creation (a new mail or a threaded reply-all) and update — a hallucinated command can at most create an unsent draft in your Drafts folder. Safe default for autonomous agents, MCP servers, and "let Claude poke around my mailbox" sessions where you can't fully review every tool call.
28
+ **This is the most important property.** 173 GET endpoints + 3 read-only POST (two searches + free/busy lookup) + 3 POST (create mail draft / threaded reply draft / forward draft) + 1 PATCH (update draft) = 180 commands. No `send-mail`, no `create-event`, no `upload-file`, no `delete-anything`. The only write operations are draft creation (a new mail, a threaded reply-all, or a forward) and update — a hallucinated command can at most create an unsent draft in your Drafts folder. Safe default for autonomous agents, MCP servers, and "let Claude poke around my mailbox" sessions where you can't fully review every tool call.
29
29
 
30
30
  ### One call gets the full email context
31
31
 
@@ -56,7 +56,7 @@ Pass `--include-metadata true` on any `*-as-markdown` (or `convert-mail-attachme
56
56
 
57
57
  ### Extract embedded images from documents
58
58
 
59
- `extract-drive-item-images` (OneDrive / SharePoint), `extract-mail-attachment-images` (Outlook attachments), and `extract-local-file-images` (a file **on disk** — no Graph, no login) pull the embedded images out of a **docx, xlsx, pptx, or pdf**. For Office files it reads the OOXML media parts (png/jpg/gif/bmp/tiff/webp/svg) — including original full-resolution / un-cropped originals and images on hidden slides that the rendered view never shows. SVG rides back as its XML source (which carries the diagram's own text labels); legacy vector (emf/wmf) and audio/video are skipped. For a PDF it walks every page via [unpdf](https://github.com/unjs/unpdf) (a pure-JS, no-native-deps pdf.js build) and re-encodes each painted image as PNG — page-oriented, so it captures images as drawn on each page (it does not reach layer-hidden/unpainted XObjects or the full uncropped original behind a clipped image). Pair with the global `--output-dir <dir>` to write every image to a folder (the directory is auto-created and each `base64` becomes a `savedTo` path); without it the bytes ride back base64-encoded so a vision model can read them directly.
59
+ `extract-drive-item-images` (OneDrive / SharePoint), `extract-mail-attachment-images` (Outlook attachments), and `extract-local-file-images` (a file **on disk** — no Graph, no login) pull the embedded images out of a **docx, xlsx, pptx, or pdf**. For Office files it reads the OOXML media parts (png/jpg/gif/bmp/tiff/webp/svg) — including original full-resolution / un-cropped originals and images on hidden slides that the rendered view never shows. SVG rides back as its XML source (which carries the diagram's own text labels); legacy vector (emf/wmf) and audio/video are skipped. For a PDF it walks every page via [unpdf](https://github.com/unjs/unpdf) (a pure-JS, no-native-deps pdf.js build) and re-encodes each painted image as PNG — page-oriented, so it captures images as drawn on each page (it does not reach layer-hidden/unpainted XObjects or the full uncropped original behind a clipped image). Pair with the global `--output-dir <dir>` to write every image to a folder (the directory is auto-created and each `base64` becomes a `savedTo` path); without it the bytes ride back base64-encoded so a vision model can read them directly. The same OOXML / PDF image extraction runs over every file **inside a `.zip`** when you pass `convert-local-file --include-images true`: each archive entry gains an `images` array, so a screenshot pasted into a zipped document is still reachable in one call.
60
60
 
61
61
  The CLI follows any SharePoint media-transform redirect internally, so the LLM never has to fetch an external URL.
62
62
 
@@ -68,10 +68,11 @@ The CLI follows any SharePoint media-transform redirect internally, so the LLM n
68
68
 
69
69
  No Azure app, no tenant admin. The CLI captures the same token the Teams web client uses — works for any Microsoft 365 account, personal or enterprise.
70
70
 
71
- **Login flow:** the CLI drives a Playwright-launched Edge/Chrome window through the Teams sign-in, captures the tokens, and caches them at `~/.ask-marcel/token-cache.json` (0600).
71
+ **Login flow:** the CLI drives a Playwright-launched Edge/Chrome window through the Teams sign-in, captures the tokens, and caches them at `~/.ask-marcel/token-cache.json` (0600). Running `login` again (even when already signed in) reports all four cached tokens — basic, elevated (M365), and the two Teams-chat substrate tokens (chatsvcagg / ic3) — each with its time-left and refresh route: basic/chatsvcagg/ic3 refresh automatically from the cached refresh token, while the elevated token is re-captured only on an interactive login. `login --force` ignores the cache and re-captures every token in one browser pass (the persistent profile is reused, so you are usually not re-prompted for credentials) — the only way to refresh the elevated token while the basic one is still valid. `scopes-check` reports the same four tokens without opening a browser.
72
72
 
73
73
  ```bash
74
- ask-marcel-office login
74
+ ask-marcel-office login # sign in, or show all four tokens' status if already signed in
75
+ ask-marcel-office login --force # re-capture every token, ignoring the cache
75
76
  ```
76
77
 
77
78
  ### Stable error envelope with actionable hints
@@ -176,7 +177,7 @@ The `AuthManager` interface is two async methods that return `Result<T, AuthErro
176
177
 
177
178
  ## Deep docs
178
179
 
179
- - **[All 179 commands](docs/COMMANDS.md)** — per-category tables with required params + Graph endpoint
180
+ - **[All 180 commands](docs/COMMANDS.md)** — per-category tables with required params + Graph endpoint
180
181
  - **[Usage guide](docs/USAGE.md)** — output formats, OData passthrough, `--output-path`, pagination, library API, architecture, configuration, quality gates
181
182
  - **[Machine-readable manifest](docs/commands.json)** — JSON for programmatic discovery (LLM tool-loops, IDE plugins, MCP servers); also importable via `import manifest from 'ask-marcel-office-cli/commands.json'`
182
183
  - **[QA playbook](docs/QA-PLAYBOOK.md)** — the repeatable full-surface health-check procedure (offline gates, parameter matrix, conversion contracts, live Graph drift probes) used to audit each release