slidemind 0.3.2 → 0.3.3
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slidemind",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Connect Claude Code to the slidemind PowerPoint add-in — build and edit native, on-brand PowerPoint decks against the active corporate design, from the terminal.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "statworx",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slidemind",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Connect Codex to the slidemind PowerPoint add-in — build and edit native, on-brand PowerPoint decks against the active corporate design. Requires the slidemind CLI (npm install -g slidemind); the skills explain the install when it is missing.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "statworx",
|
package/AGENTS.md
CHANGED
|
@@ -230,7 +230,7 @@ slidemind uninstall --for <target> # remove the skill (also clears the bundle
|
|
|
230
230
|
|
|
231
231
|
**Engine ops are moving off the task pane.** An add-in that advertises `engineRoutes` in `/api/cli/capabilities` answers discovery, search, download and slide extraction on the CLI session itself (`GET /api/cli/engines`, `POST /api/cli/searches`, `GET /api/cli/searches/:id/results/:sel/{image,thumbnail,slide,source-presentation}`), so those commands need **no PowerPoint window at all** — the searchId is server-owned, `--to` becomes a no-op, and multi-environment routing goes by the deck's bound design (`.bundle-ref.json`), never by an open window's origin. Older add-ins keep relaying every one of them through the pane (`client.resolveEngineBackend()` returns null → `requirePaneHost()`), so **never remove the pane path and never raise `minCliVersion` for this**. Live `insert-slide` and reading an unsaved open deck stay pane-bound — that is Office.js physics, but even there the *extraction* backend is the one that **minted the searchId** (`client.resolveSearchBackend()`), never the target window's origin: with two environments connected those differ, and spending a server-owned id on the wrong one 404s as an "expired search" no re-search can clear.
|
|
232
232
|
|
|
233
|
-
**Corpus identity is the user's own sign-in, resolved live.** The pane-free engine routes run as the USER: the CLI attaches the delegated Graph + SharePoint tokens `slidemind login` minted (body fields `graphApiToken`/`spApiToken` on POST, headers `x-slidemind-graph-token`/`x-slidemind-sp-token` on the byte GETs), and the backend resolves Entra + `sg:` site-group membership from them per request (cached ~10 min server-side). There is NO stored permission snapshot anymore — that Redis record, its capture points, and `permissions_stale` were removed on both sides. Without usable tokens the corpus routes answer `403 login_required` (403, not 401 — the CLI transport reserves 401 for a dead session), rendered through `client.loginRequiredBlocker(err)`; but before ever sending a token-less request the CLI attempts the sign-in ITSELF (`ensureSignedIn`: opens the browser, blocks up to
|
|
233
|
+
**Corpus identity is the user's own sign-in, resolved live.** The pane-free engine routes run as the USER: the CLI attaches the delegated Graph + SharePoint tokens `slidemind login` minted (body fields `graphApiToken`/`spApiToken` on POST, headers `x-slidemind-graph-token`/`x-slidemind-sp-token` on the byte GETs), and the backend resolves Entra + `sg:` site-group membership from them per request (cached ~10 min server-side). There is NO stored permission snapshot anymore — that Redis record, its capture points, and `permissions_stale` were removed on both sides. Without usable tokens the corpus routes answer `403 login_required` (403, not 401 — the CLI transport reserves 401 for a dead session), rendered through `client.loginRequiredBlocker(err)`; but before ever sending a token-less request the CLI attempts the sign-in ITSELF (`ensureSignedIn`: opens the browser, blocks up to 30 min — nothing expires while the tab waits — once per process), so the blocker only appears when the human refused or abandoned it. When a pane-ready window is open, `search` **relays through it** instead of blocking (one stderr note; the searchId is then the pane's, and every next step names that window), and the ops that cannot be replayed pane-side — anything bound to an opaque `searchId` — name that open pane as the route to a fresh search. Plan: `docs/slidemind-cli-connect/13-pane-free-authoring.md` + `15-graph-delegated-cli.md`.
|
|
234
234
|
|
|
235
235
|
**The two ops that stay pane-bound self-heal a presId churn.** Every pane reconnect mints a NEW presId for the same window, so `push`'s insert and `insert-slide` re-list the registry and re-match the window before giving up: `waitForPaneReady` matches the same presId, then `fileName`+`brandId`, then — when a Save-As renamed the window mid-run — the **design fingerprint alone** (`presFP == brandId`), and only when exactly one connected window carries it (two windows on one design are indistinguishable, and pushing into the wrong one is worse than waiting). `engineOpWithPaneWait` takes that window identity plus an opt-in `retargetOnMissing`, which **only the live insert sets**: for an idempotent engine read a 404 is the search record talking, not the window, so waiting on the registry would just stall the agent (`isMissingPresentationError` keeps a coded 404 like `unknown_search` out of it). Both retries re-send the SAME `operationId`, so the pane-side dedup makes them safe; both retry exactly ONCE and then surface the wake-PowerPoint blocker — `push` by saving the rendered `.pptx` next to the deck rather than throwing the bytes away, `insert-slide` by naming the click and the window-free `add-slide` alternative.
|
|
236
236
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slidemind",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Connect Claude Code, Codex & opencode to the slidemind PowerPoint add-in — let your coding agent build and edit native, on-brand PowerPoint decks against your active corporate design, from the terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -63,10 +63,14 @@ function sharePointScope(resource) {
|
|
|
63
63
|
|
|
64
64
|
const DEFAULT_AUTHORITY = "https://login.microsoftonline.com";
|
|
65
65
|
|
|
66
|
-
// How long the loopback listener waits for the browser to come back.
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
|
|
66
|
+
// How long the loopback listener waits for the browser to come back. Generous
|
|
67
|
+
// on purpose: the user may be away from the machine when the tab opens (MFA
|
|
68
|
+
// phone in another room, a coffee), and NOTHING here expires meanwhile — the
|
|
69
|
+
// authorize page keeps, the auth code is only minted when they finish, and the
|
|
70
|
+
// listener is a local ephemeral port. The cap only stops an abandoned login
|
|
71
|
+
// from holding a terminal forever. (`setup` passes its own much shorter cap —
|
|
72
|
+
// mid-onboarding is not a parked sign-in.)
|
|
73
|
+
const LOGIN_TIMEOUT_MS = 30 * 60 * 1000;
|
|
70
74
|
|
|
71
75
|
// Refresh this long before the access token actually expires, so a token handed
|
|
72
76
|
// to a long download doesn't die mid-transfer.
|