slidemind 0.3.4 → 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.
- package/.agents/plugins/marketplace.json +2 -0
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +5 -5
- package/bin/slidemind.mjs +535 -134
- package/package.json +1 -1
- package/skills/create-slides/SKILL.md +718 -127
- package/skills/search/SKILL.md +217 -57
- package/src/bridge/build-and-push.mjs +3 -3
- package/src/bridge/bundle.mjs +91 -36
- package/src/bridge/capture.mjs +34 -0
- package/src/bridge/client.mjs +81 -23
- package/src/bridge/config.mjs +21 -2
- package/src/bridge/engine-download.mjs +26 -7
- package/src/bridge/recolor.mjs +46 -0
- package/src/bridge/setup-claim.mjs +7 -1
- package/src/builders/build.mjs +179 -5
- package/src/builders/gate-server.mjs +25 -36
- package/src/builders/gate-session.js +28 -48
- package/src/builders/lint-fix.mjs +88 -0
- package/src/builders/plan-overlay.js +507 -136
- package/src/builders/plan.mjs +337 -60
- package/src/builders/review-overlay.js +126 -109
- package/src/builders/review.mjs +118 -64
- package/src/builders/storyboard-markdown.mjs +15 -0
- package/src/builders/storyboard-schema.mjs +23 -6
- package/src/builders/visual-families.mjs +20 -4
- package/src/lib/adopt.mjs +10 -6
- package/src/lib/conversions.mjs +26 -6
- package/src/lib/overwrite-guard.mjs +14 -1
- package/src/lib/reconcile.mjs +15 -4
- package/src/pptx/tags.mjs +49 -0
|
@@ -5,51 +5,170 @@ description: Author branded slide decks and individual slides against the active
|
|
|
5
5
|
|
|
6
6
|
# slidemind-create-slides
|
|
7
7
|
|
|
8
|
-
This skill is **thin workflow glue for the local harness**. Everything that determines how a deck is
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
This skill is **thin workflow glue for the local harness**. Everything that determines how a deck is
|
|
9
|
+
authored, styled, and rendered lives in the **slidemind PowerPoint add-in** and reaches you through
|
|
10
|
+
a **materialized design bundle**:
|
|
11
|
+
|
|
12
|
+
- The **brand** — tokens, `corporate-design.css`, the `design.md` brand rules, the closed layout
|
|
13
|
+
palette, brand assets — is served per corporate design.
|
|
14
|
+
- The **authoring workflow craft** — create, edit, composition, layouts, authoring contract,
|
|
15
|
+
build/export — is the add-in's deployment-shipped `workflow/*.md`, served on the same bundle so
|
|
16
|
+
the local harness reads **byte-identical** guidance to the in-app design agent.
|
|
12
17
|
- The **`.pptx` render** happens server-side in the add-in. There is no local exporter.
|
|
13
18
|
|
|
14
|
-
So this file owns only what is genuinely CLI-specific: the **first-step design-bundle gate**, a
|
|
19
|
+
So this file owns only what is genuinely CLI-specific: the **first-step design-bundle gate**, a
|
|
20
|
+
compact **intake/plan**, the **create flow**, and the **command mapping** that translates the
|
|
21
|
+
workflow vocabulary — the harness-neutral verbs defined in the bundle's `workflow/flow.md` and
|
|
22
|
+
spoken throughout `workflow/*.md` — into your `slidemind` CLI commands. Read the workflow + brand
|
|
23
|
+
from the bundle; never restate or duplicate them here.
|
|
24
|
+
|
|
25
|
+
Brand sample slides are private inputs to the add-in's concept generator. They are not authoring
|
|
26
|
+
references and are deliberately not materialized into the local bundle. From the concept pass
|
|
27
|
+
onward, re-read only `decks/<slug>/concepts/concept-slide-NN.png`; when a concept is unavailable,
|
|
28
|
+
fall back to the approved storyboard plus `design.md` and the chosen layout, never to samples.
|
|
15
29
|
|
|
16
|
-
**slidemind is a CLI you drive directly.** Run `slidemind <command>` in your shell — the same way
|
|
30
|
+
**slidemind is a CLI you drive directly.** Run `slidemind <command>` in your shell — the same way
|
|
31
|
+
you'd run `git` or `npm`. There is no separate tool layer to go through; every step below is a real
|
|
32
|
+
command you type.
|
|
17
33
|
|
|
18
34
|
## Create a todo list (before your first command)
|
|
19
35
|
|
|
20
|
-
The moment this skill activates on an authoring task, **create a todo list of the workflow stages**
|
|
36
|
+
The moment this skill activates on an authoring task, **create a todo list of the workflow stages**
|
|
37
|
+
in your harness's task tracker — before you run anything — and keep it current: mark each stage done
|
|
38
|
+
as you complete it. This is `workflow/flow.md` → *track the stages*; the list is what keeps the
|
|
39
|
+
later stages (above all the review gate) from being skipped. The stages, as they run over the CLI:
|
|
21
40
|
|
|
22
41
|
1. `slidemind ready` — session preflight (*First step* below)
|
|
23
|
-
2. Clarify with the user — the content **and the output target** (*Intake → plan* below; needs no
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
2. Clarify with the user — the content **and the output target** (*Intake → plan* below; needs no
|
|
43
|
+
host, so it can run while `ready` executes)
|
|
44
|
+
3. Plan sign-off — `slidemind plan <deck>` (every from-scratch request — one slide included)
|
|
45
|
+
4. Concept mockups — `slidemind concepts <deck>`, then immediately inspect every mockup (anything
|
|
46
|
+
authored from an approved plan, a single slide included; see *The create flow* below). **The FILES ON DISK are the
|
|
47
|
+
truth, not the command output you saw.** Generation takes 1–2 minutes and your harness may
|
|
48
|
+
time the command out, showing you only progress lines while the detached process finishes
|
|
49
|
+
writing the PNGs — output that ends mid-progress means TIMED OUT, never "no mockups". The
|
|
50
|
+
moment the command returns (complete or cut off): run `ls decks/<slug>/concepts/`. PNGs
|
|
51
|
+
listed → re-run `slidemind concepts <deck>` once (it returns the full path list instantly for
|
|
52
|
+
already-generated mockups) and Read every file. **Claiming the concepts are missing requires
|
|
53
|
+
double evidence**: `asset-plan.md` may say "no mockups" ONLY when BOTH the re-run's output
|
|
54
|
+
printed zero paths AND `ls decks/<slug>/concepts/` is empty — quote both in the file.
|
|
55
|
+
Authoring a concept-seeded deck without having Read the concept PNGs that exist on disk is the
|
|
56
|
+
single largest fidelity failure this workflow has; nothing about a truncated stdout excuses it.
|
|
57
|
+
**User-provided images** go into this command, classified from the user's words: a sketch or
|
|
58
|
+
mockup to build ("build it like this") → `--concept <file>[@N,M]` (it becomes the mockup for
|
|
59
|
+
those slides, no generation); a look to emulate ("in this style") → `--style <file>[@N,M]`
|
|
60
|
+
(leads the generation; repeatable; `@` omitted = all slides). A photo or logo to place on a slide
|
|
61
|
+
is not a concept input: copy it into `decks/<slug>/assets/` and list it in `asset-plan.md`.
|
|
62
|
+
5. Source assets — write `decks/<slug>/asset-plan.md` from the concepts, then search + download
|
|
63
|
+
every item in it (*The create flow* steps 2–3). **This stage is not optional and not mergeable
|
|
64
|
+
into authoring**: it is done when every plan item is checked off with a filename or marked
|
|
65
|
+
`(no result)` after its search ran. A deck with concept mockups and an empty `assets/` beyond
|
|
66
|
+
the brand chrome means this stage was skipped, not completed.
|
|
67
|
+
6. Author the slides
|
|
68
|
+
7. Draft check — `slidemind view-draft`
|
|
69
|
+
8. Review gate — `slidemind review`, the moment the deck builds clean
|
|
70
|
+
9. Deliver — `slidemind push` or `slidemind build-pptx`, whichever target was locked in stage 2
|
|
71
|
+
|
|
72
|
+
**Changing slides that already exist runs a shorter list.** When the deck is on disk and the
|
|
73
|
+
request targets slides in it — "make slide 13 clearer", "rescope 12 and 13", "fix the spacing",
|
|
74
|
+
comments on a delivered deck — the stages are `ready` → edit → `view-draft` → `review` → deliver.
|
|
75
|
+
Stages 2–5 do not run: there is nothing to plan and no mockup to render, the live slide is the
|
|
76
|
+
starting point (the in-app equivalent is the manager's route B, `approvedPlan: null`; the design
|
|
77
|
+
worker's small-edit fast path keeps no todo board at all). Updating `plan.md` afterwards is optional
|
|
78
|
+
bookkeeping and never re-opens the plan gate — once a deck has passed a review, the CLI treats
|
|
79
|
+
`plan.md` as a record, not a contract. The full route definitions are in *Intake → plan* below; new
|
|
80
|
+
slides added to an existing deck are from-scratch work and run the full list.
|
|
81
|
+
|
|
82
|
+
**Deliver is the last todo — the task ends when the slides are delivered.** Don't add a "sanity
|
|
83
|
+
pass" or "report back" step after it: the visual QA already happened at the draft check and the user
|
|
84
|
+
already approved at the review gate, so on approval you push/build directly and stop. Each stage's
|
|
85
|
+
full definition and the ordering invariants live in the bundle's `workflow/flow.md` — read it right
|
|
86
|
+
after `ready` succeeds.
|
|
87
|
+
|
|
88
|
+
**Concept mockups (stage 4) are a mandatory authoring stage, not an optional aid.** After plan
|
|
89
|
+
sign-off, for anything authored from an approved plan — one slide as much as a deck — you **always**
|
|
90
|
+
run `slidemind concepts <deck>` and
|
|
91
|
+
**immediately Read every generated `concept-slide-NN.png` at full detail**. Use this first,
|
|
92
|
+
deck-wide viewing pass to inventory the imagery, pictograms, factual/content checks, and other
|
|
93
|
+
searches each slide needs; do those searches before authoring. This discovery read does **not**
|
|
94
|
+
replace the fresh per-batch concept read immediately before JSX creation in *The create flow*.
|
|
95
|
+
The durable visual anchors are the repo-relative files under
|
|
96
|
+
`decks/<slug>/concepts/concept-slide-NN.png`, never an earlier chat image or temporary attachment;
|
|
97
|
+
after any continuation, re-list that directory and reopen the files from those paths.
|
|
98
|
+
Rebuild each mockup toward its target — this is the local-harness equivalent of the in-app manager's
|
|
99
|
+
*unconditional* concept pass on every from-scratch delegation (`generateConceptImages` fires for
|
|
100
|
+
every delegation carrying an approved plan). It degrades benignly: if it returns no mockups (exit 0 —
|
|
101
|
+
the add-in can't generate them) you author from the storyboards alone, but the *attempt* is not
|
|
102
|
+
optional. Skip it only for targeted work on slides that **already exist** — an edit or a rework,
|
|
103
|
+
which designs from the live slide and never had a plan to render mockups from.
|
|
34
104
|
|
|
35
105
|
Two gate invariants you must never break — one per gate, equally binding:
|
|
36
106
|
|
|
37
|
-
- **Never jump from clarify to authoring
|
|
38
|
-
|
|
107
|
+
- **Never jump from clarify to authoring** — the plan sign-off gate (`slidemind plan <deck>`,
|
|
108
|
+
stage 3) always sits between. Writing `decks/<slug>/slides/*.jsx` before that gate has
|
|
109
|
+
returned `DECISION: approved` is the single most common way this workflow goes wrong — it means
|
|
110
|
+
the user never actually signed off on the story. **There is no small-request exception**: one new
|
|
111
|
+
slide runs the same gate with a one-beat plan. The only work that skips it is a change to slides
|
|
112
|
+
that already exist.
|
|
113
|
+
- **Never jump from authoring to deliver** — the draft check and an approved review gate always sit
|
|
114
|
+
between.
|
|
115
|
+
|
|
116
|
+
## After a context summarization (compaction recovery)
|
|
117
|
+
|
|
118
|
+
Long deck runs can exceed the context window mid-task; the harness then replaces the transcript
|
|
119
|
+
with a summary. **Everything you only held in chat — viewed concept images, search results, the
|
|
120
|
+
asset inventory, workflow rules you read from the bundle — is gone; the files on disk are not.**
|
|
121
|
+
When you notice you are running from a summary (or after any interruption/continuation), do NOT
|
|
122
|
+
improvise from the summary and do NOT restart finished work. Recover state from disk, in this
|
|
123
|
+
order, then resume at the first incomplete stage:
|
|
124
|
+
|
|
125
|
+
1. `decks/<slug>/plan.md` — the approved story.
|
|
126
|
+
2. `decks/<slug>/asset-plan.md` — per-slide organisms + which assets are downloaded vs. missing
|
|
127
|
+
(unchecked items still need their search + fetch).
|
|
128
|
+
3. `ls decks/<slug>/slides/ decks/<slug>/assets/ decks/<slug>/concepts/` — what already exists.
|
|
129
|
+
4. Re-read `<bundle>/workflow/create.md` if you are still before or inside authoring, and reopen
|
|
130
|
+
the concept PNGs for the slides not yet authored (batches of ≤3) before writing them.
|
|
131
|
+
|
|
132
|
+
The stage todo list still binds after a summary: a summary that says the deck is "mostly done" is
|
|
133
|
+
never a reason to skip the remaining stages (assets, draft check, review gate).
|
|
39
134
|
|
|
40
135
|
## Bootstrap (set yourself up — don't make the user do it)
|
|
41
136
|
|
|
42
|
-
**The first step of every session is `slidemind ready`** (continuing an existing deck: `slidemind
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
- **
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
137
|
+
**The first step of every session is `slidemind ready`** (continuing an existing deck: `slidemind
|
|
138
|
+
ready <deck>`). In one call it verifies authorization, connection, and CLI version; resolves the
|
|
139
|
+
design the add-in has open; downloads or refreshes that design's bundle; and — given a deck arg —
|
|
140
|
+
binds the deck to it.
|
|
141
|
+
|
|
142
|
+
- **Exit 0** → you're fully set up. Read `workflow/flow.md` (the stage spine) and `design.md` from
|
|
143
|
+
the reported `bundleDir` and start planning.
|
|
144
|
+
- **Non-zero** → the CLI names exactly one blocker and one `nextAction`; do what it says. (The two
|
|
145
|
+
blockers that ever need the user are handled in *First step* below.)
|
|
146
|
+
|
|
147
|
+
`ready` drives the `slidemind` CLI, which reaches PowerPoint through the add-in's **cloud relay** —
|
|
148
|
+
no local server. Patch a missing CLI yourself; **connecting** needs the user once (they hold the
|
|
149
|
+
add-in's identity):
|
|
150
|
+
|
|
151
|
+
- **CLI missing** (`slidemind` not on `PATH`): `npm install -g slidemind` — that alone is the fix.
|
|
152
|
+
Only run `slidemind init --for <claude|codex|opencode|all>` ((re)deploys this skill) when this
|
|
153
|
+
skill did **not** come from a plugin: if the `SKILL.md` you are reading sits under a harness
|
|
154
|
+
plugin cache (`~/.claude/plugins/…`, `~/.codex/plugins/…`), the plugin already supplies it and
|
|
155
|
+
`init` would plant a second copy that drifts on the next plugin update. `npx slidemind <command>`
|
|
156
|
+
runs one-off without a global install; `slidemind --version` confirms PATH; `slidemind update`
|
|
157
|
+
upgrades (`--ref <version>` to pin) — unless the CLI itself came from a plugin, in which case
|
|
158
|
+
update it there.
|
|
159
|
+
- **Not connected:** `ready` exits with `not_connected` — the CLI cannot start a connection by
|
|
160
|
+
itself, because the claim that carries the deployment's address is minted in the add-in. Ask the
|
|
161
|
+
user to open PowerPoint → slidemind → **Settings → General → Connect CLI**, press the **link
|
|
162
|
+
button**, and copy the command shown (press **CLI already installed?** for the short `slidemind
|
|
163
|
+
setup …` form). Have them paste it to you and run it **verbatim** — it connects, refreshes the
|
|
164
|
+
skills, and runs `ready` itself. Add `--no-install --for none` only if their install must not be
|
|
165
|
+
touched. `slidemind whoami` lists connected environments.
|
|
166
|
+
|
|
167
|
+
The CLI is **multi-environment**: connect once per backend (local / dev / prod) and every command
|
|
168
|
+
fans out across all of them, tags each open window with its `env`, and routes to the right backend
|
|
169
|
+
automatically — no manual switching. (Scope first-use authorization with `--backend <url>`; scope
|
|
170
|
+
later calls with `--backend <url|env>`.) A normal user connects to the baked-in production backend
|
|
171
|
+
only.
|
|
53
172
|
|
|
54
173
|
## Connecting the CLI (one-time; you guide the user)
|
|
55
174
|
|
|
@@ -58,68 +177,271 @@ PowerPoint — not here. Every organization runs its own slidemind backend, so a
|
|
|
58
177
|
unconnected CLI has no address to reach and nothing to discover it from; the
|
|
59
178
|
authenticated add-in knows both, and mints a one-time claim carrying its address.
|
|
60
179
|
|
|
61
|
-
**1 — Ask for the command.** Tell the user to open the **slidemind add-in** task pane → **Settings**
|
|
180
|
+
**1 — Ask for the command.** Tell the user to open the **slidemind add-in** task pane → **Settings**
|
|
181
|
+
→ **General** → **Connect CLI**, press the **link button**, and press **Copy command**. If they
|
|
182
|
+
already have the CLI, **CLI already installed?** swaps it to the shorter `slidemind setup …` form;
|
|
183
|
+
either works.
|
|
62
184
|
|
|
63
|
-
**2 — Run it verbatim.** Paste it exactly as given. It redeems the claim, saves the session,
|
|
185
|
+
**2 — Run it verbatim.** Paste it exactly as given. It redeems the claim, saves the session,
|
|
186
|
+
installs the CLI globally if needed, deploys the skills into every coding agent on the machine, and
|
|
187
|
+
finishes by running `ready` — so no `init` and no add-in restart belong to this flow.
|
|
64
188
|
|
|
65
|
-
**3 — If it fails.** A claim works once and expires in ~10 minutes; on *already used or expired*,
|
|
189
|
+
**3 — If it fails.** A claim works once and expires in ~10 minutes; on *already used or expired*,
|
|
190
|
+
ask for a fresh one. The pane flips to **Connected** by itself once the claim is spent.
|
|
66
191
|
|
|
67
192
|
## First step — `slidemind ready` (before anything else, every time)
|
|
68
193
|
|
|
69
|
-
Everything about how a deck is authored, styled, and rendered is shaped by the corporate design
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
`
|
|
194
|
+
Everything about how a deck is authored, styled, and rendered is shaped by the corporate design
|
|
195
|
+
**the add-in has open**, and every brand rule you follow is read from that design's **materialized
|
|
196
|
+
bundle**. `slidemind ready` gets you there in one call: it walks the connection ladder (a saved
|
|
197
|
+
session → reachable backend → CLI version), picks which design to build against, downloads or
|
|
198
|
+
refreshes that design's bundle (incremental — unchanged files cost nothing), and — when you pass a
|
|
199
|
+
deck — binds the deck to it by writing `<deck>/.bundle-ref.json`. PowerPoint does not have to be
|
|
200
|
+
open: the designs cached on this machine are a first-class source.
|
|
201
|
+
|
|
202
|
+
- **New work:** `slidemind ready` — picks + materializes a design's bundle so you can read its
|
|
203
|
+
`design.md` while planning.
|
|
204
|
+
- **Continuing a deck:** `slidemind ready <deck>` — same, and the deck's own binding is what it
|
|
205
|
+
picks.
|
|
206
|
+
|
|
207
|
+
**The design is the user's choice; `ready` only picks a sensible default.** Its order is: an
|
|
208
|
+
explicit `--brand <presFP>`, else the deck's own `.bundle-ref.json`, else the one design the
|
|
209
|
+
verified live PowerPoint windows agree on (a window whose pane is only suspended never outranks a
|
|
210
|
+
live one), else the one design cached here, else the one design the backend lists. Anything
|
|
211
|
+
that leaves several candidates is the `ambiguous_design` blocker (below). A live window is a
|
|
212
|
+
suggestion, never an authority: it only decides when nothing stronger says otherwise. And whatever
|
|
213
|
+
`ready` picked, when its `designs` list holds more than one entry the design is a Clarify question
|
|
214
|
+
(below), and the answer is applied with `slidemind ready [deck] --brand <presFP>` before anything
|
|
215
|
+
is planned.
|
|
216
|
+
|
|
217
|
+
**On exit 0** the JSON reports `presId`, `presFP`, `designName`, `designs` (every design at hand
|
|
218
|
+
— cached on this machine, open in a verified window, or listed by the backend — `{presFP, name,
|
|
219
|
+
colors, current, cached, windows}`, `colors` being the master's theme colours as hex,
|
|
220
|
+
`dk1`/`lt1`/`dk2`/`lt2`/`accent1..6`, `windows` the open PowerPoint windows on that design),
|
|
221
|
+
`windows` (every verified open window — `{presId, env, title, fileName, presFP, paneReady}`; a
|
|
222
|
+
window PowerPoint no longer has is pruned before anything is decided), `bundleDir`, `bundleEtag`,
|
|
223
|
+
`bound`, `paneSuspended`, and `engines` (`{available, envs}` — whether engine search reaches the
|
|
224
|
+
corpus without a window), with `nextAction: "Ready."`. Read `workflow/flow.md` and `design.md` from
|
|
225
|
+
`bundleDir` (cached at `${XDG_CACHE_HOME:-~/.cache}/slidemind/bundles/<presFP>/`, alongside
|
|
226
|
+
`corporate-design.css`, `layouts/*.jsx`, `layouts/layouts.css`, `assets/`, and the rest
|
|
227
|
+
of the add-in-owned `workflow/*.md`) and start planning. A render-ready window whose pane is
|
|
228
|
+
suspended still exits 0 with `paneSuspended: true` — the pane ops wait for a pane click on their
|
|
229
|
+
own; **don't treat it as a blocker.**
|
|
230
|
+
|
|
231
|
+
**A bound deck readies with NO window at all — that is the normal case, not a degraded one.**
|
|
232
|
+
`slidemind ready <deck>` for a deck that was bound once before exits 0 with `windowless: true` even
|
|
233
|
+
when PowerPoint is closed: the design identity lives in the deck's `.bundle-ref.json` and the bundle
|
|
234
|
+
syncs over a pane-free route, so its ladder is *session → bundle freshness → engine reachability*,
|
|
235
|
+
with **no pane precondition** — the pane is reported, never required. In that state authoring,
|
|
236
|
+
`view-draft`, `build`, `review`, `build-pptx`, and (where `engines.available` is true) engine search
|
|
237
|
+
and download all work end-to-end; only `push`'s insert, `insert-slide`, and `read <presId>` of an
|
|
238
|
+
open presentation need a window — the `nextAction` says exactly that. Don't ask the user to open
|
|
239
|
+
PowerPoint until one of those is actually next.
|
|
240
|
+
|
|
241
|
+
**Microsoft 365 sign-in — automatic on first need; just let it happen.** The engine surface — corpus
|
|
242
|
+
search, brand-imagery downloads, slide extraction — runs **as the user**. `ready` reports the state
|
|
243
|
+
(JSON: `m365.signedIn`, `m365.degradation`) so you know it's coming, but you never initiate it: the
|
|
244
|
+
first engine command opens the user's browser ITSELF, prints `Microsoft 365 sign-in needed — opening
|
|
245
|
+
your browser…`, and **blocks until the human finishes**. When that line appears, tell the user to
|
|
246
|
+
complete the sign-in in the browser (you cannot) and keep waiting — don't kill or re-run the
|
|
247
|
+
command. One sign-in lasts ~90 days. Rendering, bundles, and already-materialized assets never need
|
|
248
|
+
it, so a pure author→render session runs signed-out without ever seeing this.
|
|
249
|
+
|
|
250
|
+
For a deck that was **never** bound and no window is open, the one design cached here binds
|
|
251
|
+
automatically; with nothing cached `ready` asks the backend which corporate designs the user may
|
|
252
|
+
build against, and exactly one binds. Several of either stop with `ambiguous_design` (below).
|
|
253
|
+
|
|
254
|
+
**On non-zero** the CLI names exactly one blocker `{code, actor, message}` and one `nextAction`.
|
|
255
|
+
**The CLI owns the remediation text — relay `nextAction`, don't restate it.** These are the ones
|
|
256
|
+
that need the user:
|
|
257
|
+
|
|
258
|
+
- **`ambiguous_design`** — several corporate designs are at hand and nothing says which: several
|
|
259
|
+
live windows on different designs, or no live window and several designs cached / listed by the
|
|
260
|
+
backend. The payload is the same `designs` menu as on success (name, `colors`, `cached`, and
|
|
261
|
+
the open `windows` on each) plus `windows`; if the deck was last built against one of them its
|
|
262
|
+
`presFP` is `suggested`. **Ask the user which design to build against exactly as the Clarify
|
|
263
|
+
question below does — by name and colours, naming any open window on it by `title`/`fileName`,
|
|
264
|
+
never by raw id** — and mention the suggested one if present ("this deck was last built against
|
|
265
|
+
X — continue with it?"). Then re-run `slidemind ready [deck] --brand <presFP>` for the design
|
|
266
|
+
they pick (`--to <presId>` also works when they named a window).
|
|
267
|
+
- **`login_required`** — the automatic browser sign-in was refused or abandoned, so **corpus search
|
|
268
|
+
and engine downloads** stop until the user runs `slidemind login` (browser step, whenever they're
|
|
269
|
+
ready). It never blocks authoring, rendering, or the bundle — relay the line, keep working, and
|
|
270
|
+
re-run the search after they've signed in. When a slidemind pane is already open the CLI says so
|
|
271
|
+
and routes the search through that window instead: follow what it printed.
|
|
272
|
+
- **Connection blockers** (`not_connected`, `all_unreachable`, `cli_update_required`, `no_window`,
|
|
273
|
+
`not_render_ready`) — relay the CLI's `nextAction` verbatim (copy the setup command / open
|
|
274
|
+
PowerPoint / click the pane / run `slidemind update`). Connecting is walked through above.
|
|
275
|
+
(`no_window` only ever surfaces for a deck that is neither bound nor bindable from the backend's
|
|
276
|
+
design list — a bound deck rides the pane-free rung above instead.)
|
|
277
|
+
|
|
278
|
+
**The session spine** (= the stage todos you created up front): `slidemind ready` → read
|
|
279
|
+
`workflow/flow.md` + `design.md` from `bundleDir` → intake/plan (below) → `slidemind new <slug>`
|
|
280
|
+
(scaffolds **and** auto-binds the deck to the open design — zero extra download, because `ready`
|
|
281
|
+
already materialized it; `--brand <presFP>` binds to the design the user chose instead) → `slidemind plan <slug>` (plan sign-off gate for every
|
|
282
|
+
from-scratch request, one slide included) → `slidemind concepts <slug>` (mandatory concept-mockup pass for everything
|
|
283
|
+
authored from a plan, then rebuild toward each) → author → `view-draft` → `review` (mandatory, the moment the deck builds clean) →
|
|
284
|
+
deliver (`push` / `build-pptx`). `slidemind new` best-effort binds when the open design is
|
|
285
|
+
unambiguous and the bundle is already materialized; if it can't (ambiguous, or no host), it
|
|
286
|
+
scaffolds anyway and hints to run `slidemind ready <slug>`.
|
|
287
|
+
|
|
288
|
+
**Backgrounded — or closed — PowerPoint is expected to work.** Do not pre-emptively ask the user to
|
|
289
|
+
focus PowerPoint or the task pane, and never ask them to keep it foregrounded while something runs.
|
|
290
|
+
**The whole authoring loop is host-free for a bound deck** — intake → plan → concepts → author →
|
|
291
|
+
`view-draft` → `review` → `slidemind build-pptx <deck> [--out <file>]` — because the render captures
|
|
292
|
+
the slides with a local headless browser and assembles the `.pptx` server-side over the pane-free
|
|
293
|
+
brand route (streaming its own `rendering slide n/m…` progress), and engine discovery, search,
|
|
294
|
+
downloads, and slide reuse run off the connection wherever the add-in serves them
|
|
295
|
+
(`engines.available` in `ready`'s payload; older add-ins relay them through a pane instead). Exactly
|
|
296
|
+
three things need a live PowerPoint: **`push`'s insert**, **`insert-slide`**, and **`read
|
|
297
|
+
<presId>`** of an open presentation. Where a pane *is* involved, the CLI handles the wait itself: up
|
|
298
|
+
to ~2 min, one *"click the slidemind pane"* line when user help is genuinely needed, then a safe
|
|
299
|
+
retry. If you see that line, relay it once and keep waiting — do not rebuild, re-plan, or babysit.
|
|
300
|
+
If a `push` can't deliver (pane never woke, or no window at all), the rendered `.pptx` was saved
|
|
301
|
+
next to the deck (`paneSuspended` + `fallbackFile` in the result) — nothing is lost; re-run the push
|
|
302
|
+
once a window exists. Reserve the full "open PowerPoint…" instruction for when a command actually
|
|
303
|
+
reports it as the blocker.
|
|
304
|
+
|
|
305
|
+
`slidemind build`, `review`, and `view-draft` run offline, but only against a **previously
|
|
306
|
+
materialized** bundle — so `ready` (or a prior `ready`) must have succeeded at least once.
|
|
307
|
+
`build-pptx` additionally needs the backend reachable (the OOXML assembly is server-side), but no
|
|
308
|
+
PowerPoint window for a bound deck — so *"a `.pptx` file to send around"* is deliverable end-to-end
|
|
309
|
+
with PowerPoint closed.
|
|
96
310
|
|
|
97
311
|
## Two UX rules (gates + host)
|
|
98
312
|
|
|
99
|
-
- **Announce every gate, with a clickable link.** The moment `slidemind plan` or `slidemind review`
|
|
100
|
-
|
|
313
|
+
- **Announce every gate, with a clickable link.** The moment `slidemind plan` or `slidemind review`
|
|
314
|
+
starts it prints `ready at <url>` and a `BROWSER:` status line. Immediately tell the user in chat
|
|
315
|
+
whether a browser tab opened (new tab / reused tab / failed to open) and give the gate URL as a
|
|
316
|
+
clickable link — every round, and again whenever you report that you're still waiting on their
|
|
317
|
+
decision.
|
|
318
|
+
- **Add-in unreachable → block and name the tab.** When a genuinely host-required command (`push`'s
|
|
319
|
+
insert, `insert-slide`, `read <presId>`) can't reach the add-in (a connection blocker, a pane that
|
|
320
|
+
never wakes, the *click the slidemind pane* line with no effect), **stop the workflow** — don't
|
|
321
|
+
skip the step, work around it, or retry silently. Ask the user to go back into the PowerPoint tab
|
|
322
|
+
of presentation **<title/fileName>** (name it from the command output or `slidemind presentations`
|
|
323
|
+
— never a raw id), then re-run the failed command once they have. Everything before delivery keeps
|
|
324
|
+
running meanwhile — never park the whole task on a window it doesn't need.
|
|
101
325
|
|
|
102
326
|
## Intake → plan (you own this; do it in chat)
|
|
103
327
|
|
|
104
|
-
This is your mapping of `workflow/flow.md` stages 1–2 (*clarify* + *plan sign-off*). In-app, a
|
|
105
|
-
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
328
|
+
This is your mapping of `workflow/flow.md` stages 1–2 (*clarify* + *plan sign-off*). In-app, a
|
|
329
|
+
manager runs these; over the CLI the manager role collapses onto **you**, so you run the interview
|
|
330
|
+
and the sign-off directly with the user. Don't write slide JSX until the plan is agreed.
|
|
331
|
+
|
|
332
|
+
**First read which of three things the user wants**, from their words plus what you already have —
|
|
333
|
+
the deck you are working in, the file they pointed at, what you built for them a moment ago. Judge it
|
|
334
|
+
yourself and ask only when the request genuinely reads both ways. **Slide count never decides the
|
|
335
|
+
route; intent does.**
|
|
336
|
+
|
|
337
|
+
- **Author something new** ("a slide about X", "a deck for Friday", "add a closing slide", filling an
|
|
338
|
+
empty placeholder) → the full spine: plan → `slidemind plan` → `slidemind concepts` → author →
|
|
339
|
+
`view-draft` → `review` → deliver. One slide runs every one of those stages, just smaller.
|
|
340
|
+
- **Change slides that already exist** ("make slide 4 stronger", "fix the spacing", "retitle these
|
|
341
|
+
three") → **no plan, no concepts**: there is nothing to plan, the live slide is the starting point.
|
|
342
|
+
Read `workflow/edit.md`, patch that slide's own `.jsx` (adopt a foreign slide on first touch), then
|
|
343
|
+
`view-draft` → `review` → deliver. The review gate still runs — over the CLI the deliver happens
|
|
344
|
+
out of the user's sight, so it is the only place they see the change.
|
|
345
|
+
- **Reuse something that already exists elsewhere** ("do we have a slide on X?", "drop in our pricing
|
|
346
|
+
slide", "put our lighthouse icon here") → that is **`slidemind-search`**, not this create flow:
|
|
347
|
+
`slidemind search` → `download-result` / `add-slide`. Reuse is not authoring — no plan, no
|
|
348
|
+
concepts.
|
|
349
|
+
|
|
350
|
+
A request can carry two of them ("find our pricing slide and write a summary after it") — run each
|
|
351
|
+
part on its own route instead of forcing the whole thing onto one.
|
|
352
|
+
|
|
353
|
+
- **Read scope from the wording**, don't ask redundantly: single slide ("make a slide about X"),
|
|
354
|
+
small set ("add three slides on Y"), or whole deck ("a deck for Friday"). Only ask "one slide, a
|
|
355
|
+
small set, or a full deck?" when truly ambiguous.
|
|
356
|
+
- **Which corporate design — ask whenever more than one is cached.** `ready`'s `designs` list is
|
|
357
|
+
the menu: with a single entry there is no question; with several, put the choice to the user
|
|
358
|
+
**before planning**, even if PowerPoint has one of them open (that one is only the suggestion).
|
|
359
|
+
Never pick silently and never default to the open window or the deck's last binding — those
|
|
360
|
+
only chose `ready`'s `current` default, not the user's answer. Name each
|
|
361
|
+
design **and show its colours** so the user recognises it — the `name` plus its theme hexes in a
|
|
362
|
+
fixed order (`<name> — accent <accent1>, dark <dk1>, light <lt1>`, each a hex from `colors`; a
|
|
363
|
+
design without `colors` is listed by name alone), mark the `current` one, and ask which to build
|
|
364
|
+
against. Then
|
|
365
|
+
apply the answer: `slidemind ready [deck] --brand <presFP>` for the session, and `slidemind new
|
|
366
|
+
<slug> --brand <presFP>` when scaffolding a new deck. A design the user names that is not in the
|
|
367
|
+
list is not cached yet — `slidemind ready --brand <presFP>` fetches it when the backend serves
|
|
368
|
+
it; otherwise it must be opened in PowerPoint once.
|
|
369
|
+
- **Interview just enough** to pin: audience/goal, the content and its sources (none / pasted /
|
|
370
|
+
local files / existing deck / web research — a source that's already a local `.pptx` you read
|
|
371
|
+
host-free with `slidemind read <file.pptx>`), and the slide outline (each slide's role + a layout
|
|
372
|
+
*job* like cover/agenda/section/quote/closing/body — the concrete brand layout is chosen later
|
|
373
|
+
against the bundle). If the content source resolves to "none", don't silently plan from generic
|
|
374
|
+
knowledge — say so, and either interview the user for the substance (their claims, numbers,
|
|
375
|
+
examples) or offer web research before writing storyboards.
|
|
376
|
+
- **Lock the output target — it decides your deliver command.** Into the open PowerPoint (`slidemind
|
|
377
|
+
push`), or a `.pptx` file (`slidemind build-pptx`) — or an HTML preview / a mix. Infer it when the
|
|
378
|
+
wording is clear ("add a slide to this deck" → push; "make me a deck I can send around" → a file)
|
|
379
|
+
and ask only when genuinely ambiguous — but **always confirm the concrete target before
|
|
380
|
+
delivering** (which window, or which output path).
|
|
381
|
+
- **Replay and get sign-off — always, at every size.** Persist a **story-focused plan with body
|
|
382
|
+
storyboards** in `decks/<slug>/plan.md` and run the gate on it, whether the request is one slide or
|
|
383
|
+
forty. A single slide gets the same document with one `### Slide N` section: shorter, never
|
|
384
|
+
skipped. Two top-level sections in order:
|
|
385
|
+
- `## Red thread` — one presentation **move** per slide, as bullets or one arrow-separated line.
|
|
386
|
+
The number of moves MUST equal the number of `### Slide N` sections: when the user names a slide
|
|
387
|
+
count, write exactly that many moves and sections — never expand the narrative arc beyond the
|
|
388
|
+
requested count. Name the *teaching function* of each slide — short verb+noun labels for what
|
|
389
|
+
the audience is doing cognitively at that step — never its content: no claims, facts, metrics,
|
|
390
|
+
client-specific terms, slide copy, generic section names, or wording copied from these
|
|
391
|
+
instructions.
|
|
392
|
+
- `## Per-slide storyboards` — one `### Slide N: <role>` subsection per slide, each a one-sentence
|
|
393
|
+
`Core message:` followed by **exactly one** fenced `storyboard-canvas` JSON block.
|
|
394
|
+
|
|
395
|
+
The `storyboard-canvas` is a **body-only spatial sketch**, not final slide design: it plans the
|
|
396
|
+
body region only and never the template title/header/footer/logo/slide-number areas. Blocks live
|
|
397
|
+
in a 1600 × 900 coordinate space, kept inside the body-safe area (roughly x 80–1520, y 110–780);
|
|
398
|
+
position, size, and proximity must express the slide's meaning — hierarchy, sequence, causality,
|
|
399
|
+
contrast, grouping, flow direction, or the main focus — not random placement. Each block shows
|
|
400
|
+
only two visible text fields: `designElement` (the visual mechanism in up to 5 words — e.g.
|
|
401
|
+
"hub-spoke visual", "loop diagram", "timeline", "matrix", "before/after contrast", "scorecard")
|
|
402
|
+
and `content` (a 1–2 word label), plus `emphasis` ("primary"/"secondary"/"tertiary") for
|
|
403
|
+
hierarchy. A `designElement` may also name the chart family when the beat is quantitative
|
|
404
|
+
("waterfall revenue to EBIT", "combo: revenue bars + margin line", "column chart by quarter");
|
|
405
|
+
that is a plan-level choice the authoring stage honours unless the data cannot be shown that
|
|
406
|
+
way, in which case it says so at the review gate.
|
|
407
|
+
`keyMessage` is the slide's **story beat**: one plain sentence naming what this slide
|
|
408
|
+
does to move the story forward, stated abstractly — NOT the headline or copy that will appear on
|
|
409
|
+
the slide, and not the red-thread move restated. `contentNotes` is the **content draft** that
|
|
410
|
+
delivers that beat — facts, claims, examples, source points, caveats, draft copy, proof points —
|
|
411
|
+
and carries no design, layout, tone, or authoring-process instructions. It is the slide's full
|
|
412
|
+
content budget: the create stage and the concept-mockup generator build from `contentNotes` alone
|
|
413
|
+
and never add substance, so anything not in the notes will not be on the slide. Write them so the
|
|
414
|
+
slide body could be authored from them without inventing anything — every claim spelled out
|
|
415
|
+
concretely, with the numbers, named examples, or proof points that make it land. Two or three
|
|
416
|
+
abstract topic bullets ("X is expensive", "Y improves") is an unfinished draft, not a storyboard.
|
|
417
|
+
|
|
418
|
+
Judge whether two or more slides form a genuine visual series — for example a continuation,
|
|
419
|
+
progressive reveal, repeated comparison, phased journey, or recurring framework. When they do,
|
|
420
|
+
give those storyboard objects the same short, stable `visualFamily` identifier. Do not group
|
|
421
|
+
slides merely because they share a topic, and do not ask the user to make this design judgment. A
|
|
422
|
+
family tells concept generation to establish one recognizable visual system and adapt it to every
|
|
423
|
+
member's own `keyMessage`, `contentNotes`, role, and structure. It never permits copying another
|
|
424
|
+
slide's text, claims, data, or exact geometry, and it never permits dropping approved content to
|
|
425
|
+
fit the shared concept. Omit `visualFamily` for independent slides.
|
|
426
|
+
|
|
427
|
+
Choose the block count from the slide's meaning and **never default to three** (1 for a hero idea,
|
|
428
|
+
2 for a contrast or paired tension, 3 only for three genuinely distinct beats, 4–5 only for a true
|
|
429
|
+
sequence or comparison set), and vary the spatial composition across slides — avoid repeating the
|
|
430
|
+
same left/right/bottom alignment. Ban style micromanagement — no colours, fonts, or final
|
|
431
|
+
box/card counts: **the create stage owns realisation** of the approved body storyboard in the
|
|
432
|
+
corporate design. The ONE exception is the top-level `layout` field: **choose each slide's
|
|
433
|
+
layout at plan time** from `design.md` → Layout Catalog (a workhorse with a freeform body for
|
|
434
|
+
content slides; a purpose-built layout for covers/quotes/agendas; match the background tone —
|
|
435
|
+
light vs dark — to the slide's intended look) and set `"layout": "<ComponentName>"` on the
|
|
436
|
+
storyboard block. The concept generator uses it to render the mockup INTO that layout's actual
|
|
437
|
+
chrome and canvas, so the image you later rebuild already fits the stage it will live on. Use
|
|
438
|
+
this exact JSON shape:
|
|
118
439
|
|
|
119
440
|
```storyboard-canvas
|
|
120
441
|
{
|
|
121
442
|
"version": 1,
|
|
122
443
|
"slide": 1,
|
|
444
|
+
"layout": "<ComponentName from design.md's Layout Catalog>",
|
|
123
445
|
"blocks": [
|
|
124
446
|
{
|
|
125
447
|
"id": "main-visual",
|
|
@@ -141,93 +463,359 @@ This is your mapping of `workflow/flow.md` stages 1–2 (*clarify* + *plan sign-
|
|
|
141
463
|
}
|
|
142
464
|
```
|
|
143
465
|
|
|
144
|
-
Make the connection to the current deck explicit in the red thread, core messages, `keyMessage`,
|
|
145
|
-
|
|
146
|
-
|
|
466
|
+
Make the connection to the current deck explicit in the red thread, core messages, `keyMessage`,
|
|
467
|
+
or `contentNotes` whenever the work extends the open presentation, and fold in any content
|
|
468
|
+
findings from slides/files you inspected. Then run `slidemind plan <deck>`: it opens the plan as
|
|
469
|
+
**editable storyboards** — the user reorders/renames/inserts/removes slides on the red-thread
|
|
470
|
+
strip, drags/resizes/edits blocks and the content draft directly on each slide's canvas, and/or
|
|
471
|
+
leaves comments anchored to a slide or to the whole story — and it **blocks until the user
|
|
472
|
+
decides** — announce it per *Two UX rules* (browser opened? + the clickable gate URL) and give the
|
|
473
|
+
shell call a **generous timeout** (the gate waits up to 30 min; if your harness kills the call
|
|
474
|
+
early, just re-run it — the user's open tab reconnects). Outcomes: `DECISION: approved` → proceed
|
|
475
|
+
to author; `DECISION: comments` → apply the comments to `plan.md` — each is **slide-anchored** (`-
|
|
476
|
+
[Slide 3: "<beat>"] …`) or whole-story, and the batch may include a **generated story-iteration
|
|
477
|
+
instruction** (when the user restructured the red thread by adding or renaming slides, the gate
|
|
478
|
+
asks you to build storyboards and content for exactly those moves while keeping the other slides
|
|
479
|
+
intact) — (the round is persisted verbatim in `<deck>/plan-review.json` if your capture of the
|
|
480
|
+
output was truncated). Change only what the comments require and keep unaffected slides verbatim
|
|
481
|
+
(that is what makes the reviewer's per-slide "updated" badges meaningful), then **re-run the gate
|
|
482
|
+
in the same turn**. **Expect several consecutive `DECISION: comments` rounds — that is the normal
|
|
483
|
+
shape of a review, not an error.** The reviewer's tab waits while you revise (reading stays live,
|
|
484
|
+
commenting is off) and refreshes with your next run, which blocks until they decide again. So
|
|
485
|
+
never end your turn on a comments round, never claim to be "polling", and never send the user
|
|
486
|
+
back to the browser between rounds — nothing reaches them until the gate runs again. Only `DECISION: approved` or `DECISION:
|
|
487
|
+
pending` ends the loop; `DECISION: pending` → the gate timed out with no answer — not approval,
|
|
488
|
+
not rejection: don't author; wrap up telling the user the plan still awaits their sign-off and
|
|
489
|
+
re-run `slidemind plan <deck>` on their go-ahead. Loop until approved. A `plan.md` **approved in a
|
|
490
|
+
prior gate round and unchanged since** counts as approved (skip straight to authoring); any new or
|
|
491
|
+
revised plan must pass the gate. When the gate reports the user edited `plan.md` directly, re-read
|
|
492
|
+
it — the edited storyboards **are** the approved plan; author from them.
|
|
493
|
+
|
|
494
|
+
Keep planning about intent and content. The bundle is already materialized by `slidemind ready`, so
|
|
495
|
+
`design.md` is there if you need to sanity-check feasibility — but **don't dive into
|
|
496
|
+
brand/layout/composition detail until create/edit.**
|
|
147
497
|
|
|
148
498
|
## The create flow
|
|
149
499
|
|
|
150
|
-
`slidemind ready` already resolved the design source and materialized its bundle; the deck was bound
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
500
|
+
`slidemind ready` already resolved the design source and materialized its bundle; the deck was bound
|
|
501
|
+
to it by `slidemind ready <deck>` (continuing) or by `slidemind new <slug>`'s auto-bind (new work).
|
|
502
|
+
From here:
|
|
503
|
+
|
|
504
|
+
1. **Load create context, then inspect the concepts.** Read the create-stage references together —
|
|
505
|
+
`workflow/create.md` (the procedure), `workflow/composition.md` (the composition baseline),
|
|
506
|
+
`workflow/layouts.md` (palette + working area), and `workflow/authoring.md` (the substrate rules)
|
|
507
|
+
— plus the deck's `design.md` and the specific `layouts/*.jsx` the plan uses. (That is the read
|
|
508
|
+
set `workflow/create.md` → Context loading prescribes; follow it as written — `workflow/flow.md`
|
|
509
|
+
you already read after `ready`.) The approved `plan.md` is a **content contract, not a rendering
|
|
510
|
+
spec** — you drew its storyboards yourself, but approval covered the story and content, not the
|
|
511
|
+
sketch's geometry; how to interpret the `storyboard-canvas` blocks at author time (design
|
|
512
|
+
hypothesis: reinterpret freely, never transcribe coordinates, block geometry, or block labels)
|
|
513
|
+
is owned by `workflow/create.md` → Preconditions. **Generate concept mockups first — mandatory
|
|
514
|
+
for everything authored from a plan, a single slide included (stage 4).** Before
|
|
515
|
+
authoring from an approved plan, run `slidemind concepts <deck>` — the local-harness
|
|
516
|
+
equivalent of the in-app manager's *unconditional* concept pass (`generateConceptImages` fires
|
|
517
|
+
for every delegation carrying an approved plan). **Immediately after generation, Read
|
|
518
|
+
every `decks/<slug>/concepts/concept-slide-NN.png` at full detail, before any engine or content
|
|
519
|
+
search.** First list the directory and keep the literal repo-relative mapping in the task context:
|
|
520
|
+
concept `NN` maps to `decks/<slug>/concepts/concept-slide-NN.png` and later to the `NN-*.jsx`
|
|
521
|
+
slide. These workspace files are the durable source of truth across turns and compaction — never
|
|
522
|
+
rely on an earlier rendered attachment. Inventory what each mockup requires — imagery, distinct
|
|
523
|
+
pictograms, factual/content verification, annotations, and other visible organisms — and
|
|
524
|
+
**persist the inventory to disk the moment you finish it: write `decks/<slug>/asset-plan.md`**,
|
|
525
|
+
one section per slide:
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
## Slide NN — <title>
|
|
529
|
+
organisms: <the mockup's regions, hero figure, badges, satellites, chips, connectors>
|
|
530
|
+
- [ ] icon: <what it depicts> — query: "<search query>"
|
|
531
|
+
- [ ] image: <what it shows> — query: "<search query>"
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Chat context is evicted when the conversation is summarized; this file is not. Every icon
|
|
535
|
+
decision you make only in your head is lost at the next compaction — the file is the contract
|
|
536
|
+
step 2 executes and step 3 authors from. Check items off (`- [x] … — assets/engine-<id>-<n>.svg`)
|
|
537
|
+
as downloads land, so the file always shows what is still missing. This first pass is
|
|
538
|
+
deliberately deck-wide and search-oriented; it is not the fresh authoring read required in
|
|
539
|
+
step 3. Rebuild each mockup under your constraints
|
|
540
|
+
— the rebuild rule is owned by
|
|
541
|
+
`workflow/create.md` → Preconditions (reproduce the mockup's composition, hierarchy, graphic
|
|
542
|
+
mechanism, AND granularity — its organism count, badges, satellites, and annotation layers are
|
|
543
|
+
part of the target, and restraint is a colour budget, never an element budget; texts follow the
|
|
544
|
+
story). It never hard-fails: if it produces no mockups (exit 0 — the add-in can't generate them)
|
|
545
|
+
author from the storyboards alone. Skip it only for targeted work on slides that **already
|
|
546
|
+
exist** — an edit or a rework.
|
|
547
|
+
When storyboard objects share a `visualFamily`, rebuild those mockups as one recognizable visual
|
|
548
|
+
series. The lowest-numbered member is the anchor. Preserve its shape vocabulary, framing,
|
|
549
|
+
hierarchy, annotation style, illustration treatment, and spatial rhythm across the family, but
|
|
550
|
+
adapt every member's element count, sizing, arrangement, labels, emphasis, and connections to its
|
|
551
|
+
own complete `keyMessage`, `contentNotes`, role, and structure. Never copy another member's text,
|
|
552
|
+
claims, or data, never force its exact geometry, and never omit approved content because it does
|
|
553
|
+
not fit the anchor composition.
|
|
554
|
+
2. **Execute `asset-plan.md` — search and fetch every unchecked item.** Discover the available
|
|
555
|
+
image engines by listing them — `slidemind ls engines --subtype image` (no PowerPoint window
|
|
556
|
+
needed where the add-in serves the pane-free engine routes) — judge which engine fits from its
|
|
557
|
+
label and description, then run every query in `asset-plan.md` and fetch the picks.
|
|
558
|
+
(`slidemind search` without `--engine` picks an image engine the same way.) Listing the engines
|
|
559
|
+
is discovery, not sourcing: this step is done only when every `asset-plan.md` item is checked
|
|
560
|
+
off with a downloaded filename or marked `(no result)` after its search actually ran. Four
|
|
561
|
+
mechanics that waste rounds when gotten wrong:
|
|
562
|
+
- **Icon results have no preview.** `slidemind view-slide` serves slide-library results only —
|
|
563
|
+
on an image/icon search it answers "no image returned" every time, so never call it there and
|
|
564
|
+
never retry it. Pick from the `search` output's titles/scores; a download is cheap and
|
|
565
|
+
`download-result` prints each asset's size + recolor info — download first, judge from the
|
|
566
|
+
saved file, re-search once if it was wrong. At most two search rounds per need; two failed
|
|
567
|
+
downloads = mark it `(no result)` and move on.
|
|
568
|
+
- **Batch the downloads:** one `download-result --search <id> --pick <n,n,…>` per search id —
|
|
569
|
+
never one call per icon.
|
|
570
|
+
- **Quote hex colors:** `--icon-color "#<hex>"` (a value resolved from a corporate-design.css token) — an unquoted `#` makes the shell drop the
|
|
571
|
+
rest of the line.
|
|
572
|
+
- Searches come **from the file, after the concept pass** — never from plan nouns before the
|
|
573
|
+
concepts exist. The engine
|
|
574
|
+
search/reuse mechanics live in **`slidemind-search`** — use it to find and fetch imagery; the
|
|
575
|
+
create-only detail — sizing a fetched asset's box and recolouring an icon — is in *Placing engine
|
|
576
|
+
imagery* below. To pull in an **existing whole slide** (not just an image), use
|
|
577
|
+
`slidemind-search`'s `add-slide` — it folds the slide into `decks/<slug>/slides/` as a native
|
|
578
|
+
`.pptx` that coexists with your JSX in play order and survives re-push. The slide can come from
|
|
579
|
+
an engine search **or** from a local `.pptx` on disk (`add-slide --from <file.pptx> --pick <n>
|
|
580
|
+
--deck <slug>`, host-free); both fold in identically — see `slidemind-search`.
|
|
581
|
+
3. **Reopen the concepts, then author in small batches.** Once the searches and asset downloads are
|
|
582
|
+
complete, split a concept-seeded deck into batches of at most **3 slides**. For each batch, first
|
|
583
|
+
Read its matching anchored `decks/<slug>/concepts/concept-slide-NN.png` files together at full
|
|
584
|
+
detail; as the **very next tool action**, create those slides'
|
|
585
|
+
`decks/<slug>/slides/NN-<topic>.jsx` files. Put no search, command, reference read, user exchange,
|
|
586
|
+
or unrelated work between the concept images and the JSX write.
|
|
587
|
+
The deck-wide discovery read in step 1 never counts as this authoring read. A user interruption,
|
|
588
|
+
resumed turn, compaction, long wait, or unrelated tool work invalidates an earlier authoring read:
|
|
589
|
+
re-list `decks/<slug>/concepts/` if needed and reopen the affected anchored files before writing.
|
|
590
|
+
This batching is a local-harness context discipline, not a second create pass: the whole deck
|
|
591
|
+
remains one create pass and every slide file is created exactly once. Use a zero-padded numeric
|
|
592
|
+
prefix from the first file on (play order is filename order here; see the slide-file row in the
|
|
593
|
+
command mapping), one default export per slide, and one bundle layout (Mode A) or blank-content
|
|
594
|
+
layout with freeform children (Mode B), exactly as the bundle docs prescribe. **A slide whose
|
|
595
|
+
`asset-plan.md` section lists downloaded assets is UNFINISHED until its jsx references them**
|
|
596
|
+
(`<img src="./assets/engine-….svg">`, sized per *Placing engine imagery* below) — a concept full
|
|
597
|
+
of pictograms rendered as bare text boxes is a failed rebuild, not a style choice.
|
|
598
|
+
4. **Look at your own draft first (you, the agent).** This is the **draft check** in
|
|
599
|
+
`workflow/build-and-export.md` — your pre-check, *before* any human sees the deck. Two rules
|
|
600
|
+
moved early on purpose — do them NOW, not at the review gate when the run is long and attention
|
|
601
|
+
is spent: first run `slidemind build <deck>` once and fix every `[lint:warn]` it prints (a
|
|
602
|
+
mechanical pass on files you just wrote); and after any fix round below, one more `slidemind
|
|
603
|
+
view-draft` over the changed slides is mandatory — the verification must appear in your command
|
|
604
|
+
sequence, not only in prose. Run `slidemind view-draft <deck>`: it renders each authored `slides/*.jsx` to a per-slide PNG and hands the
|
|
605
|
+
images back to you — **nothing is pushed, no `.pptx` is written, no review gate opens**. For
|
|
606
|
+
every concept-seeded slide, Read its anchored
|
|
607
|
+
`decks/<slug>/concepts/concept-slide-NN.png` and matching
|
|
608
|
+
`decks/<slug>/.draft-preview/<slide-basename>.png` **together in the same visual inspection**, in
|
|
609
|
+
batches of at most 3 pairs. Diff each pair organism by organism; a draft-only inspection does not
|
|
610
|
+
satisfy this check. Fix anything visibly wrong **in the JSX** (re-express, never delete), render
|
|
611
|
+
again, and reopen the affected anchored concept/draft pairs until each slide is sound. One round
|
|
612
|
+
usually suffices. It runs
|
|
613
|
+
locally against the materialized bundle, so it needs no awake pane and no open host once the
|
|
614
|
+
bundle has been downloaded once. Two faithful limits to know: a slide on a **purpose-built (Mode
|
|
615
|
+
A) layout** (cover/divider/agenda) and a **reused native `.pptx`** slide have no freeform region
|
|
616
|
+
to capture, so they come back as a status line, not an image — judge those at the full-deck
|
|
617
|
+
`review`/`build` step below. Do this self-check before the human review gate; don't push a draft
|
|
618
|
+
you haven't looked at.
|
|
619
|
+
5. **The review gate — the moment the deck builds clean.** This is the **review gate** in
|
|
620
|
+
`workflow/build-and-export.md`; the CLI's gate command is `slidemind review <deck>`. Run it the
|
|
621
|
+
instant the authored set builds clean — before any deliver, without asking whether the user wants
|
|
622
|
+
a review. It builds the HTML preview first (the same lint the render enforces, so a gate that
|
|
623
|
+
*opens* is a clean build; while lint errors remain it exits non-zero — fix and re-run), then
|
|
624
|
+
opens the browser with a spatial comment overlay and **blocks until the user decides** (host-free
|
|
625
|
+
— no open PowerPoint needed for the gate). Announce it per *Two UX rules*: tell the user the
|
|
626
|
+
browser opened and give the clickable gate URL. **Blocking is the point: give the shell call a
|
|
627
|
+
generous timeout (the gate waits up to 30 min) and let it sit — a long quiet wait means the user
|
|
628
|
+
is reviewing, not that something hung. Never cancel it; if your harness kills the call early,
|
|
629
|
+
just re-run it (the user's open tab reconnects).** The verdict prints to stdout:
|
|
630
|
+
- `DECISION: approved` → proceed to the deliver the user chose at intake: `slidemind push <deck>`
|
|
631
|
+
(into PowerPoint) or `slidemind build-pptx <deck>` (to a file).
|
|
632
|
+
- `DECISION: comments` → the user left spatially-anchored notes, each citing a
|
|
633
|
+
`slides/<file>.jsx:line:col`, the source line, the click position, and a **round tag** (`[2,
|
|
634
|
+
round 1] …`) — plus a readonly-layout note where the click landed on a layout slot. A pin
|
|
635
|
+
carrying an *older* round was dropped on the previous render, so read the file before you edit
|
|
636
|
+
it rather than trusting the cited line blindly. **Edit the cited files in place at the given
|
|
637
|
+
line and re-run `slidemind review <deck>` in the same turn.** **Expect several consecutive
|
|
638
|
+
`DECISION: comments` rounds — that is the normal shape of a review, not an error.** The user's
|
|
639
|
+
tab waits while you fix (browsing stays live, pinning is off) and refreshes with your next run,
|
|
640
|
+
which blocks until they send the next batch of pins or approve. So never end your turn on a
|
|
641
|
+
comments round, never claim to be "polling", and never send the user back to the browser
|
|
642
|
+
between rounds — nothing reaches them until the gate runs again. Addressed pins come back as read-only ghost pins so the user can
|
|
643
|
+
confirm each note was worked in. Only `DECISION: approved` or `DECISION: pending` ends the
|
|
644
|
+
loop. Nothing is exported on a comments round. **Every round is persisted verbatim in
|
|
645
|
+
`<deck>/review.json`** — if your shell capture of the gate's output was truncated or lost
|
|
646
|
+
(backgrounded command, clipped scrollback), read that file for the complete comment list; never
|
|
647
|
+
guess at missing comments or ask the user to re-type them.
|
|
648
|
+
- `DECISION: pending` → the gate timed out with no answer (the user stepped away). Not approval,
|
|
649
|
+
not rejection — **do not deliver**. Wrap up your turn: tell the user the preview is still
|
|
650
|
+
waiting for their review and that on their go-ahead you'll re-run `slidemind review <deck>`
|
|
651
|
+
(their tab reconnects).
|
|
652
|
+
|
|
653
|
+
`slidemind review` is the only step that pauses; `push`/`build-pptx` never pause — they render
|
|
654
|
+
pane-free (local capture + server-side assembly, with live per-slide progress). **CLI exports
|
|
655
|
+
happen out of the user's sight, so the flow invariant — *the user sees every change before the
|
|
656
|
+
task is done* — makes re-review mandatory here: every deliver is preceded by an approved review
|
|
657
|
+
of exactly what it delivers. After any later slide change, the deck re-enters `slidemind review`
|
|
658
|
+
before it can be pushed or exported again — never deliver an unreviewed change.** If several
|
|
659
|
+
presentations are open, confirm **which one to push into** first (it can differ from the design
|
|
660
|
+
source `slidemind ready` locked in). After approval, run the push without asking; it works while
|
|
661
|
+
PowerPoint is backgrounded, and the CLI itself waits + retries if the pane is needed (see *First
|
|
662
|
+
step* above). If a push still times out, the rendered `.pptx` is saved next to the deck — re-run
|
|
663
|
+
`push` after the user clicks the pane, without rebuilding.
|
|
664
|
+
|
|
665
|
+
**On a clean approve + deliver, the task is done.** Report what landed (slide count + target) and
|
|
666
|
+
stop — no sanity pass, no re-verification. The visual QA already happened at the draft check
|
|
667
|
+
(step 4) and the user signed off at the review gate.
|
|
165
668
|
|
|
166
669
|
## Manual PowerPoint edits (the reconcile loop)
|
|
167
670
|
|
|
168
|
-
The user may have edited the deck directly in PowerPoint since your last deliver — moved a shape,
|
|
671
|
+
The user may have edited the deck directly in PowerPoint since your last deliver — moved a shape,
|
|
672
|
+
retyped a line, recoloured a box. Those edits live only in that file or that window; the deck's jsx
|
|
673
|
+
knows nothing about them. `slidemind build-pptx` and `slidemind push --replace` therefore check
|
|
674
|
+
before they write, and play the changes back to you:
|
|
169
675
|
|
|
170
|
-
- **Plain text edits are already folded into your jsx** — the command prints `note: folded N manual
|
|
171
|
-
|
|
676
|
+
- **Plain text edits are already folded into your jsx** — the command prints `note: folded N manual
|
|
677
|
+
text edit(s) … into slides/<file>` and the fold is now the source of truth on disk. **Re-read that
|
|
678
|
+
file before your next edit** or you will write over it from a stale copy.
|
|
679
|
+
- **Everything else refuses the deliver** with a `RECONCILE REQUIRED` report per slide (geometry in
|
|
680
|
+
EMU, style changes, added/removed shapes) and exit code non-zero. Nothing was written or pushed.
|
|
172
681
|
|
|
173
682
|
On a `RECONCILE REQUIRED`:
|
|
174
683
|
|
|
175
|
-
1. **Fold every listed change into the slide's jsx** — the user made them on purpose; losing them is
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
684
|
+
1. **Fold every listed change into the slide's jsx** — the user made them on purpose; losing them is
|
|
685
|
+
unacceptable. Translate geometry deltas into **layout intent** (spacing, order, relative sizing,
|
|
686
|
+
which region a thing sits in) — never literal offsets, absolute coordinates, or
|
|
687
|
+
transform/translate hacks bolted onto a working composition. Recreate added shapes as jsx
|
|
688
|
+
elements; drop deleted ones. If a folded position genuinely cannot fit the content area,
|
|
689
|
+
re-express its intent (reflow, reorder, resize) rather than discarding it.
|
|
690
|
+
2. Lines marked `[preserved]` are foreign add-in content (e.g. an embedded chart) — do **not**
|
|
691
|
+
recreate them; they are spliced back into the rendered slide automatically.
|
|
692
|
+
3. **Re-run the same command.** The re-run proceeds: the report was acknowledged
|
|
693
|
+
(`decks/<slug>/.reconcile-ack.json`), and only a NEW manual edit re-arms the check. The deck
|
|
694
|
+
changed, so the flow invariant applies — re-run `slidemind review <deck>` before delivering
|
|
695
|
+
again.
|
|
696
|
+
4. **Do this silently.** Reconcile is bookkeeping, not a deliverable: never explain the report, the
|
|
697
|
+
baseline, or your folding steps, and never ask the user about it. Fold and carry on with their
|
|
698
|
+
actual request in the same turn. At most one short clause in your final answer ("kept your manual
|
|
699
|
+
layout change").
|
|
700
|
+
|
|
701
|
+
`--force` on either command **discards the user's manual edits** and writes anyway. It is a last
|
|
702
|
+
resort, only on the user's explicit say-so — never reach for it to get past a report you could fold.
|
|
181
703
|
|
|
182
704
|
Three refusals are not foldable and need the user, not a retry:
|
|
183
705
|
|
|
184
|
-
- `the live deck contains N slide(s) not in this deck` — a whole-deck replace would delete slides
|
|
185
|
-
|
|
186
|
-
|
|
706
|
+
- `the live deck contains N slide(s) not in this deck` — a whole-deck replace would delete slides
|
|
707
|
+
someone added by hand or with another tool. Push **without** `--replace` to insert instead, or ask
|
|
708
|
+
the user what should happen to them.
|
|
709
|
+
- `<file> was edited in PowerPoint …` naming slides with no jsx behind them (a reused native slide,
|
|
710
|
+
or one pushed by another deck) — build to a different target with `--out <other file>` so their
|
|
711
|
+
edits survive, or ask.
|
|
712
|
+
- `backend does not support manual-edit reconcile` / `the live deck could not be inspected` — the
|
|
713
|
+
add-in is older than this contract, or its PowerPoint build cannot export slides. Tell the user to
|
|
714
|
+
update the slidemind add-in. Do not paper over it with `--force`.
|
|
715
|
+
|
|
716
|
+
## Charts (create-authoring specifics)
|
|
717
|
+
|
|
718
|
+
A real series of numbers is a `<Chart>` element in your JSX — one self-closing element that renders
|
|
719
|
+
as a native PowerPoint chart with its own embedded workbook, so the client double-clicks it and
|
|
720
|
+
edits the data in Excel. Never hand-draw a chart from divs, bars, lines or SVG, and never let a
|
|
721
|
+
table stand in for one; conceptual figures (process, framework, hub, timeline with no measured
|
|
722
|
+
values) are not charts and stay HTML/SVG. The type list, the props each type accepts, the
|
|
723
|
+
theme-first colour rule (leave `seriesStyle` off and the brand paints it) and the kinds that are
|
|
724
|
+
out of the model live in the bundle's `workflow/authoring.md` → Charts — read them there, don't
|
|
725
|
+
guess; the composition rule (one chart is the hero; the accent marks ONE series or point, not six)
|
|
726
|
+
is in `workflow/composition.md` → Charts in the composition. Three local-harness facts: numbers the
|
|
727
|
+
user states in chat go straight into the chart's `data` prop; this harness has **no analyst
|
|
728
|
+
subagent**, so when the numbers live in a file you do the aggregation yourself, say what you did,
|
|
729
|
+
and put the RESULT in the props (the deck carries the numbers, never a pointer to your workspace);
|
|
730
|
+
and both the HTML preview and `slidemind view-draft` paint a **stand-in** for a chart, not
|
|
731
|
+
PowerPoint's render — judge a chart's final look from the pushed slide (the review gate warns the
|
|
732
|
+
user on chart slides itself). Editing a chart later — yours, or one on a slide
|
|
733
|
+
the deck adopted from PowerPoint — is editing its `<Chart>` props and re-rendering; an adopted
|
|
734
|
+
chart keeps its `data-sm-source-id` and its `conversions/<stem>.slide.pptx` (never delete either:
|
|
735
|
+
the push patches the client's own chart part through them, so its Excel data and styling
|
|
736
|
+
survive). To see what a chart on a live slide plots, `slidemind read <presId> --mode raw` prints a
|
|
737
|
+
data table per chart; `slidemind read <file.pptx>` (host-free) reports text only, no chart data.
|
|
187
738
|
|
|
188
739
|
## Placing engine imagery (create-authoring specifics)
|
|
189
740
|
|
|
190
|
-
Finding and fetching engine imagery is `slidemind-search`'s job (`slidemind search` → `slidemind
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
741
|
+
Finding and fetching engine imagery is `slidemind-search`'s job (`slidemind search` → `slidemind
|
|
742
|
+
download-result`). What follows is **create-only**: how to size and colour a fetched asset so it
|
|
743
|
+
reads on-brand in your JSX, honoured in both the `slidemind build` preview and the render.
|
|
744
|
+
|
|
745
|
+
Engine results land as files referenced with `<img src="./assets/<file>">`. These facts are specific
|
|
746
|
+
to the local harness (the bundle's `workflow/*.md` stay harness-neutral):
|
|
747
|
+
|
|
748
|
+
- **Size the box from the asset's own dimensions.** Both `slidemind search` (from the engine index,
|
|
749
|
+
before any fetch) and `slidemind download-result` (measured from the delivered bytes) print each
|
|
750
|
+
image's intrinsic `width×height`. **Use it.** A plain `<img>` is stretched to whatever box you
|
|
751
|
+
write, so a box whose aspect ratio disagrees with the asset ships a distorted picture. Derive one
|
|
752
|
+
side from your layout and compute the other from the printed ratio. `object-fit: contain`/`cover`
|
|
753
|
+
is honoured in the render as well as the preview, but it is a *fallback*, not a substitute: it
|
|
754
|
+
converts a wrong ratio into letterboxing or a crop, both of which you chose blind. When the size
|
|
755
|
+
prints as `(size unknown)`, the format carried no readable header — give the asset a square-ish
|
|
756
|
+
box and check it at the draft check.
|
|
757
|
+
- **Never open the SVG to find out whether it recolours.** `slidemind download-result` prints a
|
|
758
|
+
`recolor` descriptor for each asset — `{ recolorable, mode, applied, note }`, where `mode` is
|
|
759
|
+
`currentColor`, `mono`, `multicolor`, or `raster`. Read it; that *is* the answer.
|
|
196
760
|
- **Two ways to colour an icon, both honoured in the `slidemind build` preview *and* the render:**
|
|
197
|
-
- **Bake it in (prefer this):** pass `--icon-color <hex>` — a hex you resolve from a token in the
|
|
198
|
-
|
|
199
|
-
|
|
761
|
+
- **Bake it in (prefer this):** pass `--icon-color <hex>` — a hex you resolve from a token in the
|
|
762
|
+
bundle's `corporate-design.css` — to `slidemind download-result`. Works for any `recolorable`
|
|
763
|
+
glyph and the colour is in the saved file, so preview and render always agree. The tint is
|
|
764
|
+
applied by the add-in, so on the window-free path it can be **refused**: the asset is then saved
|
|
765
|
+
in its original colours and the `recolor` note says so. Believe the note over your request — to
|
|
766
|
+
actually bake the colour in, re-run the search and the download with `--to <presId>` against an
|
|
767
|
+
open PowerPoint window.
|
|
768
|
+
- **Tint via CSS:** set `color` to a token on the `<img>`. This works only for `mode:
|
|
769
|
+
"currentColor"` icons (the preview inlines the SVG so `color` resolves, and the render
|
|
770
|
+
substitutes `currentColor`). A `mono` icon will not respond to CSS colour — bake it instead.
|
|
771
|
+
- **Batch the fetch.** Pull every icon a slide needs in one call — `slidemind download-result
|
|
772
|
+
--search <id> --pick <n,n,…> --deck <deck> [--icon-color <hex,hex,…>]` (one colour applies to all
|
|
773
|
+
picks, or give one per pick; add `--to <presId>` only on an add-in that still relays the fetch
|
|
774
|
+
through a pane, which the `search` output names) — the downloads run concurrently. Don't run
|
|
775
|
+
`download-result` once per icon.
|
|
200
776
|
|
|
201
777
|
## Command mapping (the workflow vocabulary ⇄ your CLI)
|
|
202
778
|
|
|
203
|
-
The bundle's `workflow/*.md` speak the harness-neutral verbs defined in `workflow/flow.md` →
|
|
779
|
+
The bundle's `workflow/*.md` speak the harness-neutral verbs defined in `workflow/flow.md` →
|
|
780
|
+
Vocabulary. You are the local harness — this is your mapping:
|
|
204
781
|
|
|
205
782
|
| Verb (`workflow/flow.md`) | Your equivalent (local harness) |
|
|
206
783
|
|---|---|
|
|
207
784
|
| (session setup — a CLI-only stage before the spine) | `slidemind ready [deck]` — the one-shot session start: connection ladder + design resolution (open window, the deck's own binding, or `--brand <presFP>`) + bundle materialize + deck bind. **Run it first, every session** (see *First step* above). `slidemind download-bundle` is the lower-level materialize-only command `ready` now covers — you rarely call it directly |
|
|
208
785
|
| **track the stages** | your harness's task tracker — explicitly create the stage todo list before your first command and keep it current (see *Create a todo list* above) |
|
|
209
|
-
| **clarify** / **plan sign-off** | intake stays in chat with the user (above); for
|
|
210
|
-
| concept mockups (mandatory
|
|
786
|
+
| **clarify** / **plan sign-off** | intake stays in chat with the user (above); for every from-scratch request — one slide included — persist `decks/<slug>/plan.md` as `## Red thread` + `## Per-slide storyboards` (one `storyboard-canvas` JSON block per slide), then run `slidemind plan <deck>` — the same blocking `DECISION:` gate contract as `slidemind review`, on the plan (renders editable storyboards — red-thread strip + spatial canvases — plus slide-anchored comments; expect several comment rounds; loop until approved) |
|
|
787
|
+
| concept mockups (mandatory for every from-scratch set, after plan sign-off) | `slidemind concepts <deck>` — renders one image mockup per approved-plan slide into the durable repo-relative path `decks/<slug>/concepts/concept-slide-NN.png`; immediately Read all of them for image/content search, then after searches reopen them in batches of at most 3 immediately before writing the matching `NN-*.jsx`. Re-list and reopen those paths after any interruption or continuation; never rely on an earlier chat image. The rebuild rule is owned by `workflow/create.md` → Preconditions. It never hard-fails: on an empty result (exit 0 — the add-in can't generate them) author from the storyboards alone, but for anything authored from a plan — one slide included — you always run it. Skip only for targeted work on slides that already exist (edit/rework) |
|
|
211
788
|
| **read** / **list** the workspace | read the files from the materialized bundle dir (`<bundle>/…`) and your `decks/<slug>/` |
|
|
212
|
-
| **create / update a slide file** | write `decks/<slug>/slides/NN-<topic>.jsx` on disk with a **zero-padded numeric prefix** (`01-cover.jsx`, `02-agenda.jsx`, …) — over the CLI, "the ordered set you hand to build & push" is expressed as **numeric-aware filename order**; there is no ordered-list channel, so reordering = renaming files |
|
|
213
|
-
|
|
|
214
|
-
| **draft check** | `slidemind view-draft <deck>` — renders each `slides/*.jsx` to a per-slide PNG and returns the images to **you**; **no push, no `.pptx`, no review gate**. Look, fix the JSX, view again. Host-free once the bundle is materialized. Freeform slides only — purpose-built (Mode A) and reused native `.pptx` slides report as a status line (judge those at `review`/`build`). This is your self-check; `slidemind review` is the *human* gate |
|
|
789
|
+
| **create / update a slide file** | write `decks/<slug>/slides/NN-<topic>.jsx` on disk with a **zero-padded numeric prefix** (`01-cover.jsx`, `02-agenda.jsx`, …) — over the CLI, "the ordered set you hand to build & push" is expressed as **numeric-aware filename order**; there is no ordered-list channel, so reordering = renaming files. For a concept-seeded create or structural rewrite, the immediately preceding tool action must Read the matching anchored concept path(s) at full detail |
|
|
790
|
+
| **draft check** | `slidemind view-draft <deck>` — renders each `slides/*.jsx` to `decks/<slug>/.draft-preview/<slide-basename>.png` and returns the images to **you**; **no push, no `.pptx`, no review gate**. Read each concept/draft path pair together, fix the JSX, render, and pair again. A draft-only inspection does not count. Host-free once the bundle is materialized. Freeform slides only — purpose-built (Mode A) and reused native `.pptx` slides report as a status line (judge those at `review`/`build`). This is your self-check; `slidemind review` is the *human* gate |
|
|
215
791
|
| **build & push** | `slidemind push <deck>` (into the open PowerPoint — the insert needs a window) · `slidemind build-pptx <deck> [--out <file>]` (to a `.pptx` file — **host-free** for a bound deck: no PowerPoint window at all) — deliver whichever target was locked at intake; both render server-side via the bridge and for a bound deck the render itself is pane-free |
|
|
216
|
-
| **the review gate** | `slidemind review <deck>` — builds the HTML preview (lint-clean or it doesn't open), serves it with a spatial comment overlay and **blocks until the user decides**, then prints `DECISION: approved` or `DECISION: comments` (each comment cited to `slides/<file>.jsx:line:col` + the round it was dropped on). On approve → deliver (`slidemind push` / `build-pptx`); on comments → edit the cited files and re-run `slidemind review` in the same turn (addressed pins show as ghost pins);
|
|
792
|
+
| **the review gate** | `slidemind review <deck>` — builds the HTML preview (lint-clean or it doesn't open), serves it with a spatial comment overlay and **blocks until the user decides**, then prints `DECISION: approved` or `DECISION: comments` (each comment cited to `slides/<file>.jsx:line:col` + the round it was dropped on). On approve → deliver (`slidemind push` / `build-pptx`); on comments → edit the cited files and re-run `slidemind review` in the same turn (addressed pins show as ghost pins); the user pins as many comments as they like and sends them as one batch (Approve is off while unsent pins exist); expect several comment rounds. CLI delivers happen out of the user's sight, so **every deliver follows an approved review of what it delivers — re-run `review` after any slide change**. `push`/`build-pptx` never pause; only `review` does. |
|
|
217
793
|
| **inspect the deck** | `slidemind read [presId\|file.pptx] [--mode summary\|raw]` — one verb, two sources: pull the current content of an open presentation (a presId; **host-required** — it reads the live, possibly unsaved file) **or** read a local `.pptx` on disk (a file path; host-free — no PowerPoint, no pairing). Prefer the file path when the deck is saved. `summary` = per-slide outline; `raw` = each slide's plain text — to inspect what's there before editing. Plain text, not authoring markup |
|
|
218
794
|
| **discover engines** (`list_engines`) | `slidemind ls engines [--type <collection\|search\|scope>] [--subtype <image\|slide\|template\|content>]` — the live catalog is the only engine list (the bundle carries none); pick an `id` from it, never guess one. Needs no PowerPoint window where the add-in serves the pane-free engine routes. It also lists **search scopes** for unfiltered corpus search — those belong to `slidemind-search`, not to imagery |
|
|
219
795
|
| **engine search / fetch** | **`slidemind-search`** owns the engine search + reuse mechanics (`slidemind search` → `slidemind download-result`, plus whole-slide reuse via `add-slide`). For placing a fetched asset in your JSX, size its box from the printed `width×height`, pass `--icon-color` / batch with `--pick <n,n,…>` and colour per *Placing engine imagery* below |
|
|
796
|
+
| **generate an image** | `slidemind imagen "<prompt>" --deck <deck> [--out <name.png>] [--size <size>] [--quality <tier>]` — use only for a planned photograph or illustration when engine sourcing returned nothing; never generate pictograms |
|
|
220
797
|
| **see** a live slide | no CLI analog — once delivered, the user is looking at the result; your visual authority runs at the draft check and the review gate instead |
|
|
221
798
|
|
|
222
|
-
Everything else in `workflow/*.md` — the composition craft, the substrate/authoring rules, the
|
|
799
|
+
Everything else in `workflow/*.md` — the composition craft, the substrate/authoring rules, the
|
|
800
|
+
layout discovery and slot/working-area rules, the visual quality bar (applied at the draft check) —
|
|
801
|
+
applies to you unchanged.
|
|
223
802
|
|
|
224
803
|
## The brand and the workflow both live in the bundle, not here
|
|
225
804
|
|
|
226
|
-
Do not restate brand values (colour, type scale, spacing, layout names, accent discipline) or
|
|
805
|
+
Do not restate brand values (colour, type scale, spacing, layout names, accent discipline) or
|
|
806
|
+
re-derive the authoring/composition craft in this file or in slide files — they are in the bundle's
|
|
807
|
+
`design.md` and `workflow/*.md`. Read them and follow them. Don't load external UI/design-taste
|
|
808
|
+
plugins during slide work; compose against the bundle's layouts and tokens. If the corporate design
|
|
809
|
+
moves mid-task (`bundle_etag_stale`), the CLI self-heals: it refreshes the bundle and retries the
|
|
810
|
+
render on its own — afterwards re-read the bundle's `design.md` before authoring anything new, since
|
|
811
|
+
the rules may have changed.
|
|
227
812
|
|
|
228
813
|
## Failure modes the render lint can't catch
|
|
229
814
|
|
|
230
|
-
Render-time lint rejects contract violations (unsupported CSS, bad imports, remote `<img>` URLs —
|
|
815
|
+
Render-time lint rejects contract violations (unsupported CSS, bad imports, remote `<img>` URLs —
|
|
816
|
+
the add-in's capability-table engine; `slidemind build` runs the same engine locally from the
|
|
817
|
+
bundle). It can't catch content-shaped failures; check for these **at the draft check** (step 4,
|
|
818
|
+
before the review gate) — not after delivery:
|
|
231
819
|
|
|
232
820
|
- Layout-default / placeholder text leaking through an unfilled prop.
|
|
233
821
|
- A bullet list standing in for a structured idea (process, comparison, timeline).
|
|
@@ -239,4 +827,7 @@ Render-time lint rejects contract violations (unsupported CSS, bad imports, remo
|
|
|
239
827
|
|
|
240
828
|
## Where the deck lives
|
|
241
829
|
|
|
242
|
-
`decks/<slug>/` is created in the **current working directory** (the shell's pwd when the skill was
|
|
830
|
+
`decks/<slug>/` is created in the **current working directory** (the shell's pwd when the skill was
|
|
831
|
+
invoked). Every `slidemind` command and `mkdir` resolves `decks/` against that cwd — don't `cd` into
|
|
832
|
+
the skill's install directory. The materialized bundle lives in the cache dir above, not under the
|
|
833
|
+
deck.
|