slidemind 0.2.3 → 0.3.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +65 -15
- package/README.md +36 -2
- package/bin/slidemind.mjs +1609 -225
- package/install.ps1 +70 -0
- package/install.sh +65 -0
- package/package.json +3 -1
- package/skills/create-slides/SKILL.md +47 -19
- package/skills/search/SKILL.md +26 -18
- package/src/bridge/build-and-push.mjs +431 -38
- package/src/bridge/capture.mjs +12 -1
- package/src/bridge/client.mjs +1214 -107
- package/src/bridge/config.mjs +193 -1
- package/src/bridge/engine-download.mjs +61 -8
- package/src/bridge/graph-auth.mjs +859 -0
- package/src/bridge/http-json.mjs +15 -6
- package/src/bridge/secrets.mjs +75 -0
- package/src/bridge/setup-claim.mjs +6 -0
- package/src/builders/build.mjs +3 -1
- package/src/builders/gate-server.mjs +156 -0
- package/src/builders/gate-session.js +355 -0
- package/src/builders/plan-overlay.js +507 -225
- package/src/builders/plan.mjs +169 -98
- package/src/builders/resolve-skill.mjs +64 -2
- package/src/builders/review-overlay.js +390 -302
- package/src/builders/review.mjs +136 -50
- package/src/lib/adopt.mjs +407 -0
- package/src/lib/conversions.mjs +263 -0
- package/src/lib/overwrite-guard.mjs +91 -0
- package/src/lib/reconcile-ack.mjs +46 -0
- package/src/lib/reconcile.mjs +306 -0
- package/src/lib/slide-guids.mjs +143 -0
- package/src/pptx/fill/engine.mjs +181 -135
- package/src/pptx/hidden-ole.mjs +22 -1
- package/src/pptx/slide-swap.mjs +23 -1
- package/src/pptx/tags.mjs +676 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slidemind",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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
|
+
"version": "0.3.0",
|
|
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
|
@@ -27,7 +27,29 @@ npx --yes slidemind@latest setup smc1_<claim>
|
|
|
27
27
|
npx runs the package from its cache but never installs it, so `cmdSetup` does
|
|
28
28
|
the persistent work itself: decode the claim → redeem it → save the session →
|
|
29
29
|
`npm install -g slidemind@latest` → deploy the skills → run `ready`. The user
|
|
30
|
-
needs nothing but Node beforehand
|
|
30
|
+
needs nothing but Node beforehand — and for a machine without even that, the
|
|
31
|
+
tarball ships two **zero-prerequisite bootstrap scripts** the add-in can print
|
|
32
|
+
instead, served publicly by the npm CDNs (same trick as the Claude marketplace
|
|
33
|
+
JSON — private repo, public tarball):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# macOS / Linux
|
|
37
|
+
curl -fsSL https://unpkg.com/slidemind/install.sh | sh -s -- smc1_<claim>
|
|
38
|
+
# Windows
|
|
39
|
+
powershell -NoProfile -ExecutionPolicy Bypass -Command "& ([scriptblock]::Create((irm https://unpkg.com/slidemind/install.ps1))) smc1_<claim>"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Each checks Node >= 18, installs — or upgrades an outdated — Node only via an
|
|
43
|
+
already-present package manager (Homebrew / winget; `install` then `upgrade`,
|
|
44
|
+
since each tool errors one of the two on an existing package), then hands off
|
|
45
|
+
to the `npx … setup` line above —
|
|
46
|
+
they host no binaries and add no channel (unlike the retired Azure-SAS
|
|
47
|
+
`install.sh`, npm stays the sole binary source). If Node cannot be installed,
|
|
48
|
+
they abort **before** the claim is touched — the one-time code stays valid and
|
|
49
|
+
the same pasted command works after a manual Node install (links printed). The
|
|
50
|
+
sh variant re-attaches `/dev/tty` as stdin so setup's TTY-gated Microsoft 365
|
|
51
|
+
sign-in still runs under `curl | sh`. `test/packaging.test.mjs` guards that
|
|
52
|
+
both ship. **There is no `init` step**: `--for auto`
|
|
31
53
|
(the default) resolves through each installer's `detect()` to the coding agents
|
|
32
54
|
actually present, minus any whose slidemind plugin already supplies the skills.
|
|
33
55
|
`init` stays for the manual-install path and for adding a harness later.
|
|
@@ -144,14 +166,16 @@ slidemind/
|
|
|
144
166
|
│ │ composition/layouts/authoring/build-export) are READ from the materialized
|
|
145
167
|
│ │ bundle — owned by the add-in.
|
|
146
168
|
│ └── search/
|
|
147
|
-
│ └── SKILL.md engine-search + slide-reuse skill (installs as slidemind-search): host gate
|
|
148
|
-
│
|
|
169
|
+
│ └── SKILL.md engine-search + slide-reuse skill (installs as slidemind-search): host gate
|
|
170
|
+
│ (insert-slide + reading an open deck only) + discover → search → pick → reuse
|
|
171
|
+
│ loop + vocabulary→CLI command map. The craft is
|
|
149
172
|
│ READ from the bundle's workflow/search.md — owned by the add-in.
|
|
150
173
|
├── src/ implementation of the slidemind CLI
|
|
151
174
|
│ ├── 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),
|
|
152
175
|
│ │ setup-claim.mjs (decode/redeem the add-in's one-command claim — the only connect path) + http-json.mjs + config.mjs (per-backend sessions)
|
|
153
176
|
│ ├── builders/ build.mjs (HTML preview), review.mjs (spatial preview-review gate + local server; stable per-deck port, graceful fallback, tab reuse across rounds), plan.mjs (plan sign-off gate) + plan-overlay.js + plan-md.mjs (markdown→HTML) + gate-server.mjs (shared gate primitives), resolve-skill.mjs (→ bundle), lint.mjs (runs the add-in's engine)
|
|
154
177
|
│ ├── pptx/ host-free local-.pptx support (fflate-based): read-local.mjs (read a file's slides — output-identical to the host read), slide-swap.mjs (fold a picked slide into a deck as native .pptx — swaps it into the lowest slot the splicer reads, then prunes the package to that slide's dependency closure so a slice carries only what it needs), zip.mjs + ooxml.mjs (shared unzip/order helpers)
|
|
178
|
+
│ ├── lib/ deck-workspace bookkeeping: adopt.mjs (rebuild a deck from a file's embedded source + convert its foreign slides through the add-in's convert-pptx route), conversions.mjs (the deck's `conversions/<stem>.json` identity+evidence records and the preserve source package push threads back), slide-guids.mjs, slide-order.mjs, reused-slides.mjs
|
|
155
179
|
│ └── installers/ per-harness installers: claude.mjs, codex.mjs, opencode.mjs, lib.mjs
|
|
156
180
|
├── archive/ retired code/assets (local exporter, icon library, brand design files) — NOT shipped
|
|
157
181
|
├── decks/ the user's working decks; sources are slides/*.jsx, design via .bundle-ref.json
|
|
@@ -166,8 +190,8 @@ We **do not** ship separate slash commands. Earlier versions had a top-level `co
|
|
|
166
190
|
## CLI surface
|
|
167
191
|
|
|
168
192
|
```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
|
|
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)
|
|
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
|
|
171
195
|
slidemind presentations # list PowerPoint windows registered with the add-in
|
|
172
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)
|
|
173
197
|
slidemind download-bundle [deck] # materialize the active corporate design's bundle locally
|
|
@@ -175,18 +199,21 @@ slidemind new <name> # scaffold ./decks/<name>/ (auto-binds to the
|
|
|
175
199
|
slidemind plan <deck> # plan sign-off gate on <deck>/plan.md; markdown editor + live preview + overall feedback, blocks for approve/comments (host-free)
|
|
176
200
|
slidemind build <deck> # build self-contained HTML preview
|
|
177
201
|
slidemind review <deck> # spatial preview-review gate; blocks for approve/comments (host-free)
|
|
178
|
-
slidemind build-pptx <deck> #
|
|
202
|
+
slidemind build-pptx <deck> # compose: add-in; template pack: host-free with --pack <dir>; never overwrites manual PowerPoint edits — text edits fold back, the rest refuses, --force discards (docs/slidemind-cli-connect/16-manual-edit-reconcile.md)
|
|
203
|
+
slidemind inspect-template-deck <deck> # normalized pack model for pack-owned validation; --pack <dir> --json
|
|
179
204
|
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
|
-
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)
|
|
205
|
+
slidemind push <deck> # render + push slides into a running PowerPoint (HOST REQUIRED); --replace reconciles the LIVE deck first (same doc), insert pushes never do
|
|
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
|
+
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
208
|
slidemind insert-slide [opts] # reuse found slide(s) live into a window (--search/--pick/--to/--at) (HOST REQUIRED)
|
|
184
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)
|
|
185
|
-
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;
|
|
187
|
-
slidemind
|
|
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
|
+
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
|
+
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)
|
|
213
|
+
slidemind login [--backend <url|env>] # sign in to Microsoft 365 (browser + PKCE); usually unnecessary — the first engine command runs this flow ITSELF and blocks until the human finishes (graph-auth `ensureSignedIn`, once per process). One sign-in mints Graph + SharePoint tokens from one refresh token; docs/slidemind-cli-connect/15-graph-delegated-cli.md
|
|
214
|
+
slidemind whoami # list every connected environment (* = default) + its Microsoft 365 sign-in state
|
|
188
215
|
slidemind use <url|env> # set the default environment
|
|
189
|
-
slidemind logout [url|env] # unpair one environment (--all unpairs every one)
|
|
216
|
+
slidemind logout [url|env] # unpair one environment (--all unpairs every one; also drops its Microsoft 365 sign-in)
|
|
190
217
|
slidemind init --for <target> # install skill into claude | codex | opencode | all | auto (also clears the bundle cache); `setup` already does this
|
|
191
218
|
slidemind uninstall --for <target> # remove the skill (also clears the bundle cache)
|
|
192
219
|
```
|
|
@@ -195,7 +222,19 @@ slidemind uninstall --for <target> # remove the skill (also clears the bundle
|
|
|
195
222
|
|
|
196
223
|
**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
224
|
|
|
198
|
-
**The
|
|
225
|
+
**The env label is routing metadata, not narrative.** Because a normal user has exactly one backend, naming it on every line is noise that makes ordinary output read like a debugging session — so human-facing output shows an env label **only when more than one backend is connected**. `src/bridge/config.mjs` owns the rule (`isMultiEnv()`, `envTag()`, `envPhrase()`); call those rather than interpolating `[${env}]` by hand, and word the sentence so it still reads with the label absent. Three things are deliberately NOT gated: `--json` payloads (agents route on `env`), `doctor` and `whoami` (reporting environments is their whole job), and any label the user just typed (`--backend prod`, `logout dev`, `use dev`) — suppressing an echo of their own argument is confusing, not quiet. `setup` decides once per run, **before** it spends the claim, so its four mentions agree with each other rather than flipping when `upsertSession` changes the count.
|
|
226
|
+
|
|
227
|
+
**No credential may reach stdout or stderr.** The CLI holds four — the per-backend `sessionToken`, a Graph refresh token, a Graph access token, and the one-time `smc1_…` claim — and none is printed on purpose. The risk is transitive: a server-controlled **response body** used verbatim as an error detail (`setup-claim.mjs` redeem failures, the Entra token endpoint, `response.body.slice(0, 400)` on every non-2xx bridge call), plus `unknown command: <argv>` echoing a claim pasted without its verb. Patching those four sites would leave the fifth to whoever adds the next route, so containment lives at the output boundary instead: `src/bridge/secrets.mjs` holds the values this process knows are secret, and `bin/slidemind.mjs` wraps `process.stdout.write`/`process.stderr.write` **once, before any command runs**, so every line, `--json` payload and error message is scrubbed on its way out. Matching is by VALUE, not by pattern — exact, no false positives on ordinary prose — and the replacement is an opaque `«secret:4f9c»` tag (4 hex of sha256) that reveals nothing while still letting two occurrences of one credential be recognised as the same. Register a secret the moment it enters memory (`readSessions`, `getGraphRefreshToken`, `requestToken`, `decodeSetupClaim`, and argv); values under 8 characters are ignored on purpose, so **test fixtures must use realistic lengths** or the guard silently cannot fail. `test/secret-containment.test.mjs` drives the real bin against a relay that deliberately echoes the credential it was sent.
|
|
228
|
+
|
|
229
|
+
**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.
|
|
230
|
+
|
|
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
|
+
|
|
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 5 min, 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
|
+
|
|
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
|
+
|
|
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.
|
|
199
238
|
|
|
200
239
|
## External skill packs (this repo ships none)
|
|
201
240
|
|
|
@@ -211,7 +250,18 @@ Some decks build from a **template pack** (`mode: "fill-template"` in the pack's
|
|
|
211
250
|
|
|
212
251
|
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
252
|
|
|
214
|
-
|
|
253
|
+
The preferred integration is explicit: `slidemind build-pptx <deck> --pack <exact-directory>`.
|
|
254
|
+
The pack directory is resolved by its owning plugin, so the CLI does not need to
|
|
255
|
+
know the plugin name or any harness cache layout. Pack-owned validation can use
|
|
256
|
+
`slidemind inspect-template-deck <deck> --pack <exact-directory> --json`, which
|
|
257
|
+
returns a normalized sequence without running domain-specific rules.
|
|
258
|
+
|
|
259
|
+
For compatibility, direct builds still resolve through `locateSkillDir()`
|
|
260
|
+
(`src/builders/resolve-skill.mjs`): `$SLIDEMIND_SKILLS_DIR/<name>` →
|
|
261
|
+
`~/.config/slidemind/skills/<name>` → `<package>/skills/<name>` → the **harness**
|
|
262
|
+
skill and plugin dirs (`~/.claude`, `~/.codex`, opencode; both `<name>` and
|
|
263
|
+
`slidemind-<name>`). This fallback remains until external packs migrate to
|
|
264
|
+
explicit paths.
|
|
215
265
|
|
|
216
266
|
Pack-dependent integration tests belong in the pack's own repo, not here.
|
|
217
267
|
|
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ Both drive the same add-in bridge, so an agent and a human end up producing the
|
|
|
22
22
|
- [Requirements](#requirements)
|
|
23
23
|
- [Install](#install)
|
|
24
24
|
- [One command (recommended)](#one-command-recommended)
|
|
25
|
+
- [No Node yet? (zero-prerequisite bootstrap)](#no-node-yet-zero-prerequisite-bootstrap)
|
|
25
26
|
- [Manual install](#manual-install)
|
|
26
27
|
- [Windows](#windows)
|
|
27
28
|
- [macOS](#macos)
|
|
@@ -73,6 +74,24 @@ The copied command carries a one-time claim that works once and expires after ab
|
|
|
73
74
|
|
|
74
75
|
Flags, if you need them: `--for <claude|codex|opencode|all|auto|none>` overrides harness detection (`auto` is the default; `none` skips skills entirely), `--no-install` skips the global npm install, `--no-ready` skips the closing readiness check.
|
|
75
76
|
|
|
77
|
+
### No Node yet? (zero-prerequisite bootstrap)
|
|
78
|
+
|
|
79
|
+
If Node isn't installed — or an outdated Node (< 18) is — a bootstrap script can take care of that too: it checks for Node 18+, installs or upgrades it where a package manager is available (Homebrew on macOS, winget on Windows), then runs the same `npx … setup` handoff. It is served straight from the published npm package, so no repository access is needed:
|
|
80
|
+
|
|
81
|
+
macOS / Linux:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
curl -fsSL https://unpkg.com/slidemind/install.sh | sh -s -- smc1_…
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Windows (PowerShell):
|
|
88
|
+
|
|
89
|
+
```powershell
|
|
90
|
+
powershell -NoProfile -ExecutionPolicy Bypass -Command "& ([scriptblock]::Create((irm https://unpkg.com/slidemind/install.ps1))) smc1_…"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If Node cannot be installed automatically, the script aborts **before** the claim is used — the one-time code stays valid, so install Node from [nodejs.org](https://nodejs.org/en/download) and paste the same command again. (`https://cdn.jsdelivr.net/npm/slidemind/install.sh` is the equivalent fallback host.)
|
|
94
|
+
|
|
76
95
|
### Manual install
|
|
77
96
|
|
|
78
97
|
If your organization distributes the Codex plugin through the admin console, the skills are already present and you only install the CLI binary:
|
|
@@ -238,6 +257,7 @@ slidemind new my-deck # scaffold ./decks/my-deck/ (auto-binds to the
|
|
|
238
257
|
slidemind build my-deck # build a self-contained HTML preview (offline)
|
|
239
258
|
slidemind review my-deck # spatial preview review: leave comments / approve in the browser (offline)
|
|
240
259
|
slidemind build-pptx my-deck # render a native .pptx via the add-in (host required)
|
|
260
|
+
# template packs may pass --pack <exact-pack-directory>
|
|
241
261
|
slidemind push my-deck # stream slides straight into an open PowerPoint (host required)
|
|
242
262
|
slidemind read <presId|file.pptx> # read an open presentation (host required) or a local .pptx on disk (host-free)
|
|
243
263
|
slidemind ls engines # list the active design's image + slide engines (host required)
|
|
@@ -279,6 +299,9 @@ slidemind plan <deck> Plan sign-off gate on <deck>/plan.md; blocks fo
|
|
|
279
299
|
slidemind build <deck> Build a self-contained HTML preview (offline)
|
|
280
300
|
slidemind review <deck> Spatial preview review; blocks for approve/comments (offline)
|
|
281
301
|
slidemind build-pptx <deck> Render a native .pptx via the add-in (host required)
|
|
302
|
+
--pack <dir> for an explicit fill-template pack
|
|
303
|
+
slidemind inspect-template-deck <deck> Emit a normalized template-deck model for pack validation
|
|
304
|
+
--pack <dir> --json [--allow-unrendered-freeform]
|
|
282
305
|
slidemind view-draft <deck> Render slides to per-slide PNGs, no push — look before review (offline once cached)
|
|
283
306
|
--to <presId> --out <dir> --open
|
|
284
307
|
slidemind push <deck> Build + push slides into an open PowerPoint (host required)
|
|
@@ -294,15 +317,21 @@ slidemind add-slide [opts] Fold slide(s) into a deck as native .pptx — f
|
|
|
294
317
|
--from <file.pptx> --pick <n[,n,...]> --deck <deck> [--at <N>] (local file; host-free; not with --search)
|
|
295
318
|
slidemind download-result [opts] Download image/icon result(s) into a deck's assets/ (host required)
|
|
296
319
|
--search <id> --pick <n[,n,...]> --deck <deck> --to <presId> [--icon-color <hex[,hex,...]>]
|
|
320
|
+
slidemind adopt <file.pptx> Rebuild a deck workspace from a .pptx — slidemind-authored slides come back
|
|
321
|
+
as their original jsx, foreign ones are converted to editable jsx where the
|
|
322
|
+
add-in offers it, the rest fold in native
|
|
323
|
+
--deck <slug> --brand <presFP> --no-convert
|
|
297
324
|
slidemind download-bundle [deck] Materialize the active corporate design locally (host required; lower-level — `ready` covers this)
|
|
298
325
|
slidemind presentations List PowerPoint windows registered with the add-in
|
|
299
326
|
slidemind read [presId|file.pptx] Read an open presentation (presId; host required) or a local .pptx on disk (file path; host-free)
|
|
300
327
|
--mode summary|raw (default raw) [--to <presId>] [--json]
|
|
301
328
|
slidemind setup <claim> One-command onboarding: connect + global install + skills + ready
|
|
302
329
|
--for <target> --no-install --no-ready --json
|
|
303
|
-
slidemind
|
|
330
|
+
slidemind login [--backend <e>] Sign in to Microsoft 365 (opens your browser) so SharePoint-backed
|
|
331
|
+
downloads and slide extractions work without an open PowerPoint window
|
|
332
|
+
slidemind whoami Show connected environment(s) and their Microsoft 365 sign-in state
|
|
304
333
|
slidemind use <url|env> Set the default environment
|
|
305
|
-
slidemind logout [url|env] Unpair an environment (--all unpairs every one)
|
|
334
|
+
slidemind logout [url|env] Unpair an environment (--all unpairs every one; drops its Microsoft 365 sign-in too)
|
|
306
335
|
slidemind init --for <target> Install the skill into a harness (clears the bundle cache)
|
|
307
336
|
<target> = claude | codex | opencode | all | auto (every harness found here)
|
|
308
337
|
Not needed after `setup` — only when adding a coding agent later
|
|
@@ -345,8 +374,13 @@ slidemind push my-deck --to <presId> # required if more than one window is
|
|
|
345
374
|
slidemind push my-deck --at 0 # insert after slide 1 (0-based index)
|
|
346
375
|
slidemind push my-deck --replace # delete every existing slide first (destructive — confirm!)
|
|
347
376
|
slidemind push my-deck --slides 02,05,07 # push only a subset of source slides
|
|
377
|
+
slidemind push my-deck --replace --accept-conversions # replace even with unconfirmed converted slides
|
|
348
378
|
```
|
|
349
379
|
|
|
380
|
+
`--replace` refuses while an adopted slide's conversion is still unconfirmed —
|
|
381
|
+
that push is the first replacement of the original. Review the slide (the
|
|
382
|
+
warning names it), or override with `--accept-conversions`.
|
|
383
|
+
|
|
350
384
|
---
|
|
351
385
|
|
|
352
386
|
## Multiple environments (for slidemind developers)
|