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 +66 -0
- package/README.md +7 -6
- package/dist/cli.js +785 -604
- package/dist/commands.json +75 -22
- package/dist/index.js +723 -576
- package/dist/infra/auth.d.ts +31 -1
- package/dist/infra/browser-auth.d.ts +3 -1
- package/dist/infra/graph-client.d.ts +26 -0
- package/dist/use-cases/commands/convert-local-file.d.ts +4 -0
- package/dist/use-cases/commands/create-forward-draft.d.ts +12 -0
- package/dist/use-cases/commands/create-reply-draft.d.ts +0 -4
- package/dist/use-cases/commands/image-extraction.d.ts +2 -1
- package/dist/use-cases/commands/login-status.d.ts +31 -0
- package/dist/use-cases/commands/login.d.ts +3 -1
- package/dist/use-cases/commands/parse-recipients.d.ts +14 -0
- package/dist/use-cases/commands/zip-archive-to-markdown.d.ts +3 -1
- package/docs/COMMANDS.md +5 -4
- package/docs/USAGE.md +1 -1
- package/package.json +1 -1
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.**
|
|
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) +
|
|
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
|
|
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
|