slidemind 0.2.3 → 0.2.4
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +31 -10
- package/README.md +4 -0
- package/bin/slidemind.mjs +1170 -199
- package/package.json +1 -1
- package/skills/create-slides/SKILL.md +18 -14
- package/skills/search/SKILL.md +24 -18
- package/src/bridge/build-and-push.mjs +19 -6
- package/src/bridge/client.mjs +890 -101
- package/src/bridge/engine-download.mjs +61 -8
- package/src/builders/resolve-skill.mjs +64 -2
- package/src/pptx/fill/engine.mjs +112 -134
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slidemind",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
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.2.
|
|
3
|
+
"version": "0.2.4",
|
|
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
|
@@ -144,8 +144,9 @@ slidemind/
|
|
|
144
144
|
│ │ composition/layouts/authoring/build-export) are READ from the materialized
|
|
145
145
|
│ │ bundle — owned by the add-in.
|
|
146
146
|
│ └── search/
|
|
147
|
-
│ └── SKILL.md engine-search + slide-reuse skill (installs as slidemind-search): host gate
|
|
148
|
-
│
|
|
147
|
+
│ └── SKILL.md engine-search + slide-reuse skill (installs as slidemind-search): host gate
|
|
148
|
+
│ (insert-slide + reading an open deck only) + discover → search → pick → reuse
|
|
149
|
+
│ loop + vocabulary→CLI command map. The craft is
|
|
149
150
|
│ READ from the bundle's workflow/search.md — owned by the add-in.
|
|
150
151
|
├── src/ implementation of the slidemind CLI
|
|
151
152
|
│ ├── bridge/ add-in local-bridge: client.mjs, bundle.mjs (materialize), build-and-push.mjs (server render; native-slide splicing), engine-download.mjs + recolor.mjs (image/icon fetch + recolour),
|
|
@@ -166,8 +167,8 @@ We **do not** ship separate slash commands. Earlier versions had a top-level `co
|
|
|
166
167
|
## CLI surface
|
|
167
168
|
|
|
168
169
|
```bash
|
|
169
|
-
slidemind ready [deck] # one-shot session start: connection ladder + design resolution + bundle download + deck bind; --to/--force/--connect-only/--json (
|
|
170
|
-
slidemind doctor # read-only
|
|
170
|
+
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)
|
|
171
|
+
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
|
|
171
172
|
slidemind presentations # list PowerPoint windows registered with the add-in
|
|
172
173
|
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)
|
|
173
174
|
slidemind download-bundle [deck] # materialize the active corporate design's bundle locally
|
|
@@ -175,15 +176,16 @@ slidemind new <name> # scaffold ./decks/<name>/ (auto-binds to the
|
|
|
175
176
|
slidemind plan <deck> # plan sign-off gate on <deck>/plan.md; markdown editor + live preview + overall feedback, blocks for approve/comments (host-free)
|
|
176
177
|
slidemind build <deck> # build self-contained HTML preview
|
|
177
178
|
slidemind review <deck> # spatial preview-review gate; blocks for approve/comments (host-free)
|
|
178
|
-
slidemind build-pptx <deck> #
|
|
179
|
+
slidemind build-pptx <deck> # compose: add-in; template pack: host-free with --pack <dir>
|
|
180
|
+
slidemind inspect-template-deck <deck> # normalized pack model for pack-owned validation; --pack <dir> --json
|
|
179
181
|
slidemind view-draft <deck> # render the deck's slides to per-slide PNGs so the agent can look before review; no push, no .pptx (host-free once the bundle is materialized)
|
|
180
182
|
slidemind push <deck> # render + push slides into a running PowerPoint (HOST REQUIRED)
|
|
181
|
-
slidemind ls engines # list the live engine catalog (image + slide; --type/--subtype) (HOST REQUIRED)
|
|
182
|
-
slidemind search "<query>" # search an engine for imagery or slides (--engine/--intent/--top) (HOST REQUIRED)
|
|
183
|
+
slidemind ls engines # list the live engine catalog (image + slide; --type/--subtype) (pane-free on add-ins with engineRoutes; HOST REQUIRED on older ones)
|
|
184
|
+
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)
|
|
183
185
|
slidemind insert-slide [opts] # reuse found slide(s) live into a window (--search/--pick/--to/--at) (HOST REQUIRED)
|
|
184
186
|
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)
|
|
185
187
|
slidemind setup <claim> # one-command onboarding from the add-in's Connect CLI button: redeem the claim + npm install -g + skills + ready (--for/--no-install/--no-ready/--json)
|
|
186
|
-
slidemind add-slide [opts] # fold slide(s) into a deck as native .pptx — from an engine (--search/--pick/--deck/--to/--at;
|
|
188
|
+
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)
|
|
187
189
|
slidemind whoami # list every connected environment (* = default)
|
|
188
190
|
slidemind use <url|env> # set the default environment
|
|
189
191
|
slidemind logout [url|env] # unpair one environment (--all unpairs every one)
|
|
@@ -195,7 +197,15 @@ slidemind uninstall --for <target> # remove the skill (also clears the bundle
|
|
|
195
197
|
|
|
196
198
|
**Multi-environment sessions.** The CLI stores one session **per backend** (`~/.config/slidemind/session.json`, v2 `{version, sessions[], default}`; the legacy single-record v1 shape is migrated on read). Connect once per environment (local / dev / prod) and every command **fans out** across all connected backends, tags each open window with its `env`, and **routes by the presentation's origin backend** automatically — no manual switching. Adding an environment is easiest with `slidemind setup <claim> --no-install --for none` — the claim carries its own backend, so nothing has to be typed or configured. There is no other way in: without a claim the CLI has no backend to talk to. Later commands may scope an existing session with `--backend <url|env>` / `SLIDEMIND_BACKEND`. A normal user connects exactly one backend.
|
|
197
199
|
|
|
198
|
-
**The design truth lives in the add-in, not the CLI.** The `.pptx` is rendered server-side over the local bridge (no local exporter), the corporate design is fetched as a bundle, brand imagery comes from the add-in's engine, and slide reuse (extract / insert / splice) executes in the add-in too. So `create`/`build-pptx`/`push`/`ls engines`/`search`/`insert-slide`/`add-slide` all
|
|
200
|
+
**The design truth lives in the add-in, not the CLI.** The `.pptx` is rendered server-side over the local bridge (no local exporter), the corporate design is fetched as a bundle, brand imagery comes from the add-in's engine, and slide reuse (extract / insert / splice) executes in the add-in too. So `create`/`build-pptx`/`push`/`ls engines`/`search`/`insert-slide`/`add-slide` all need the **slidemind add-in with an active corporate design** behind them. The engine-search + slide-reuse wire contract is in `docs/slidemind-cli-connect/11-engine-search-slide-reuse.md`; see `docs/slidemind-cli-connect/` for the rest.
|
|
201
|
+
|
|
202
|
+
**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.
|
|
203
|
+
|
|
204
|
+
When the backend's permission snapshot ages out, corpus search (only) answers `403 permissions_stale`, rendered through `client.permissionsStaleBlocker(err)` as one user-actionable line — but the snapshot backs the **pane-free path only**, since a live pane signs every request with a browser token that is strictly fresher. So 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 rather than telling the user to open an add-in that is already open. `slidemind ls engines` is the exception: `GET /api/cli/engines` is the catalog route on both add-in generations, so there is no second route to retry on and only the message widens. Plan: `docs/slidemind-cli-connect/13-pane-free-authoring.md`.
|
|
205
|
+
|
|
206
|
+
**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.
|
|
207
|
+
|
|
208
|
+
**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 `permissions_stale` is reported as a **degradation** next to the authoring ladder — never a rung, because it must not gate render or bundle. `doctor`'s engine-search line reads the same `capabilities.permissionsStale` flag off `/api/cli/readiness`, so `doctor`, `ls engines` and `search` name ONE cause for that one condition instead of three. `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.
|
|
199
209
|
|
|
200
210
|
## External skill packs (this repo ships none)
|
|
201
211
|
|
|
@@ -211,7 +221,18 @@ Some decks build from a **template pack** (`mode: "fill-template"` in the pack's
|
|
|
211
221
|
|
|
212
222
|
A pack that declares no `components.canonical` fails loudly in `layoutNumber()` — returning null instead would silently demote every master-backed slide to freeform and build a deck that quietly lost its template.
|
|
213
223
|
|
|
214
|
-
|
|
224
|
+
The preferred integration is explicit: `slidemind build-pptx <deck> --pack <exact-directory>`.
|
|
225
|
+
The pack directory is resolved by its owning plugin, so the CLI does not need to
|
|
226
|
+
know the plugin name or any harness cache layout. Pack-owned validation can use
|
|
227
|
+
`slidemind inspect-template-deck <deck> --pack <exact-directory> --json`, which
|
|
228
|
+
returns a normalized sequence without running domain-specific rules.
|
|
229
|
+
|
|
230
|
+
For compatibility, direct builds still resolve through `locateSkillDir()`
|
|
231
|
+
(`src/builders/resolve-skill.mjs`): `$SLIDEMIND_SKILLS_DIR/<name>` →
|
|
232
|
+
`~/.config/slidemind/skills/<name>` → `<package>/skills/<name>` → the **harness**
|
|
233
|
+
skill and plugin dirs (`~/.claude`, `~/.codex`, opencode; both `<name>` and
|
|
234
|
+
`slidemind-<name>`). This fallback remains until external packs migrate to
|
|
235
|
+
explicit paths.
|
|
215
236
|
|
|
216
237
|
Pack-dependent integration tests belong in the pack's own repo, not here.
|
|
217
238
|
|
package/README.md
CHANGED
|
@@ -238,6 +238,7 @@ slidemind new my-deck # scaffold ./decks/my-deck/ (auto-binds to the
|
|
|
238
238
|
slidemind build my-deck # build a self-contained HTML preview (offline)
|
|
239
239
|
slidemind review my-deck # spatial preview review: leave comments / approve in the browser (offline)
|
|
240
240
|
slidemind build-pptx my-deck # render a native .pptx via the add-in (host required)
|
|
241
|
+
# template packs may pass --pack <exact-pack-directory>
|
|
241
242
|
slidemind push my-deck # stream slides straight into an open PowerPoint (host required)
|
|
242
243
|
slidemind read <presId|file.pptx> # read an open presentation (host required) or a local .pptx on disk (host-free)
|
|
243
244
|
slidemind ls engines # list the active design's image + slide engines (host required)
|
|
@@ -279,6 +280,9 @@ slidemind plan <deck> Plan sign-off gate on <deck>/plan.md; blocks fo
|
|
|
279
280
|
slidemind build <deck> Build a self-contained HTML preview (offline)
|
|
280
281
|
slidemind review <deck> Spatial preview review; blocks for approve/comments (offline)
|
|
281
282
|
slidemind build-pptx <deck> Render a native .pptx via the add-in (host required)
|
|
283
|
+
--pack <dir> for an explicit fill-template pack
|
|
284
|
+
slidemind inspect-template-deck <deck> Emit a normalized template-deck model for pack validation
|
|
285
|
+
--pack <dir> --json [--allow-unrendered-freeform]
|
|
282
286
|
slidemind view-draft <deck> Render slides to per-slide PNGs, no push — look before review (offline once cached)
|
|
283
287
|
--to <presId> --out <dir> --open
|
|
284
288
|
slidemind push <deck> Build + push slides into an open PowerPoint (host required)
|