slidemind 0.3.5 → 0.3.12

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.5",
3
+ "version": "0.3.12",
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.5",
3
+ "version": "0.3.12",
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
@@ -121,7 +121,7 @@ Releases are **automatic on every push to `main`**. The workflow at `.github/wor
121
121
 
122
122
  Before tagging/publishing the workflow runs `scripts/sync-plugin-manifests.mjs`, which copies `package.json`'s version into `.claude-plugin/plugin.json` and `.codex-plugin/plugin.json` (Claude Code keys plugin updates off that version; Codex keys its plugin cache off it — the marketplace entries deliberately carry no version so they never drift). `scripts/release.mjs` runs the same sync locally, and `test/plugin-manifests.test.mjs` fails CI on drift.
123
123
 
124
- The publish step is gated on the `NPM_TOKEN` repo secret (an npm automation token with publish rights to `slidemind`): until it's set the workflow warns and skips publish (so tagging/releases keep working during rollout); once set, a publish failure fails the build. So most of the time you just merge to `main` and a new patch release falls out to npm.
124
+ The publish step uses npm **trusted publishing** (OIDC) — there is no `NPM_TOKEN` and no npm credential stored anywhere. The runner mints an OIDC token (`permissions: id-token: write`) that npm verifies against the trusted publisher registered on the package (npmjs.com → `slidemind` → Settings → Trusted publisher: `STATWORX` / `intern-slidemind-cli` / `release.yml`, no environment), and the release is signed with provenance. Two constraints come with it: the job runs Node 22 and upgrades npm to `@latest` first (OIDC publishing needs npm >= 11.5.1, and Node 22 still ships npm 10), and **`NODE_AUTH_TOKEN` must stay unset** — a token in the environment makes npm authenticate with it and skip OIDC entirely. So most of the time you just merge to `main` and a new patch release falls out to npm.
125
125
 
126
126
  For a **minor or major** bump, run the local helper before pushing:
127
127
 
@@ -190,12 +190,12 @@ We **do not** ship separate slash commands. Earlier versions had a top-level `co
190
190
  ## CLI surface
191
191
 
192
192
  ```bash
193
- slidemind ready [deck] # one-shot session start: connection ladder + design resolution + bundle download + deck bind; --to/--brand/--force/--connect-only/--json (a BOUND deck, an explicit --brand, or a single listed design readies with PowerPoint closed)
193
+ slidemind ready [deck] # one-shot session start: connection ladder + design pick (--brand > deck binding > the one live window design > the one cached design > the one listed design; else ambiguous_design with the full menu) + bundle download + deck bind; reports every design at hand with theme colours + every verified open window; --to/--brand/--force/--connect-only/--json (PowerPoint closed is a normal case)
194
194
  slidemind doctor # read-only diagnostics on TWO independent ladders — backend authoring (session/backend/version/engines) and live PowerPoint (windows/pane); does NOT materialize or bind — `ready` is the preflight
195
195
  slidemind presentations # list PowerPoint windows registered with the add-in
196
196
  slidemind read [presId|file.pptx] # pull an open presentation's content (presId; HOST REQUIRED) OR read a local .pptx on disk (file path; host-free) — same per-slide output (--mode summary|raw)
197
197
  slidemind download-bundle [deck] # materialize the active corporate design's bundle locally
198
- slidemind new <name> # scaffold ./decks/<name>/ (auto-binds to the open design when unambiguous + bundle already materialized; --to/--no-bind)
198
+ slidemind new <name> # scaffold ./decks/<name>/ (auto-binds to the one open design, else the one cached design, when its bundle is already materialized; --brand <presFP> binds to the design the user chose instead; --to/--no-bind)
199
199
  slidemind plan <deck> # plan sign-off gate on <deck>/plan.md; markdown editor + live preview + overall feedback, blocks for approve/comments (host-free)
200
200
  slidemind build <deck> # build self-contained HTML preview
201
201
  slidemind review <deck> # spatial preview-review gate; blocks for approve/comments (host-free)
@@ -206,7 +206,7 @@ slidemind push <deck> # render + push slides into a running PowerPo
206
206
  slidemind ls engines # list the live engine catalog (image + slide; --type/--subtype) (pane-free on add-ins with engineRoutes; HOST REQUIRED on older ones)
207
207
  slidemind search "<query>" # search an engine for imagery or slides (--engine/--intent/--top/--deck) (pane-free on add-ins with engineRoutes; HOST REQUIRED on older ones)
208
208
  slidemind insert-slide [opts] # reuse found slide(s) live into a window (--search/--pick/--to/--at) (HOST REQUIRED)
209
- slidemind imagen "<prompt>" [opts] # generate ONE image via the add-in's image model into <deck>/assets/ (--deck/--out/--size/--quality/--brand-style; connected backend, pane-free)
209
+ slidemind imagen "<prompt>" [opts] # generate ONE image via the add-in's image model into <deck>/assets/ (--deck/--out/--size/--quality; connected backend, pane-free)
210
210
  slidemind setup <claim> # one-command onboarding from the add-in's Connect CLI button: redeem the claim + npm install -g + skills + best-effort Microsoft 365 sign-in (TTY only) + ready (--for/--no-install/--no-ready/--no-login/--json)
211
211
  slidemind add-slide [opts] # fold slide(s) into a deck as native .pptx — from an engine (--search/--pick/--deck/--to/--at/--json; pane-free on add-ins with engineRoutes) or a local file (--from <file.pptx>/--pick/--deck/--at; host-free, mutually exclusive with --search)
212
212
  slidemind adopt <file.pptx> # rebuild a deck workspace from a FILE's embedded source; foreign slides convert to editable jsx through the add-in's convert-pptx route where it is served (--deck/--brand/--no-convert) — live decks are add-in-only in v1 (docs/slidemind-cli-connect/14-foreign-slide-conversion.md)
@@ -234,7 +234,7 @@ slidemind uninstall --for <target> # remove the skill (also clears the bundle
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
 
237
- **The readiness ladder is two ladders.** `bin/slidemind.mjs` authors them once: `backendBlocker(pub)` (paired → every backend unreachable → CLI below the floor) is what render, bundle and the pane-free engine routes ride on, and `paneBlocker(pub)` (no window → not render-ready → pane suspended) governs only push's insert, `insert-slide` and reading an open presentation. `connectionBlocker = backendBlocker ?? paneBlocker` keeps every pre-existing message byte-identical, `doctor` reports the two separately (`authoring` / `host` in `--json`) so an agent stops reading "pane gone" as "cannot work", and the Microsoft 365 sign-in state is reported next to the authoring ladder — never a rung, because it must not gate render or bundle (`ready`'s `m365.degradation.code: "login_required"`, computed LOCALLY from `hasGraphSession` — the backend advertises the contract via `cliLoginV1`, never per-user state). `ready`'s ladder for a **bound** deck is session → bundle freshness → (informational) engine + pane reachability: with an empty registry it materializes straight over the brand route instead of sitting out the hydration wait, and when a window IS registered the open add-in stays the design source of truth. An unbound deck with no window resolves through `GET /api/cli/brands` (capability `brandsList`, `client.listBrands()`): one design binds automatically, several stop with `ambiguous_brand` naming `--brand <presFP>`. `client.engineReachability({ backends })` is the engine half of both reports — env labels only, never a URL.
237
+ **The readiness ladder is two ladders.** `bin/slidemind.mjs` authors them once: `backendBlocker(pub)` (paired → every backend unreachable → CLI below the floor) is what render, bundle and the pane-free engine routes ride on, and `paneBlocker(pub)` (no window → not render-ready → pane suspended) governs only push's insert, `insert-slide` and reading an open presentation. `connectionBlocker = backendBlocker ?? paneBlocker` keeps every pre-existing message byte-identical (one addition: when every backend failed with code `backend_unavailable`, the add-in's `503` for "my session store did not answer", the rung is `backend_unavailable` with actor `agent` and says wait, never re-pair; a `401` is reserved for "the add-in answered: no such session", and its message no longer tells the user to `logout --all`, because `setup` replaces the backend's record in place and keeps its Microsoft 365 refresh token when the add-in-reported `oid` says the same person re-paired — a different or unknown person drops it), `doctor` reports the two separately (`authoring` / `host` in `--json`) so an agent stops reading "pane gone" as "cannot work", and the Microsoft 365 sign-in state is reported next to the authoring ladder — never a rung, because it must not gate render or bundle (`ready`'s `m365.degradation.code: "login_required"`, computed LOCALLY from `hasGraphSession` — the backend advertises the contract via `cliLoginV1`, never per-user state). `ready`'s ladder for a **bound** deck is session → bundle freshness → (informational) engine + pane reachability: the deck's own binding is the design, a window on it is targeted, none at all materializes over the brand route, and a window on a DIFFERENT design is reported, never adopted. An unbound deck picks the one design the verified live windows agree on (`resolveDesignSource` lets a live pane outrank suspended windows on other designs), else the one design cached on this machine, else the one design `GET /api/cli/brands` lists (capability `brandsList`, `client.listBrands()`); several of any stop with `ambiguous_design`, whose payload is the same `designs` menu every success carries (cached + open + listed, each with name, theme colours and its open windows) naming `--brand <presFP>`. **The zombie prune runs BEFORE any of that**: on backends advertising `paneLivenessV1` every window claiming a live pane is pinged in parallel and a dead one leaves the registry, because a closed document's webview keeps its lease and used to fake a second design — the exact false `ambiguous_design` a single open deck produced. `client.engineReachability({ backends })` is the engine half of both reports — env labels only, never a URL.
238
238
 
239
239
  ## External skill packs (this repo ships none)
240
240