slides-grab 1.2.1 → 1.2.2

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/README.md CHANGED
@@ -70,9 +70,9 @@ There are many AI tools that generate slide HTML. Almost none let you **visually
70
70
 
71
71
  ## CLI Commands
72
72
 
73
- All commands support `--slides-dir <path>` (default: `slides`).
73
+ Workflow commands support `--slides-dir <path>` (default: `slides`).
74
74
 
75
- On a fresh clone, only `--help`, `list-templates`, and `list-themes` work without a deck. `edit`, `build-viewer`, `validate`, `convert`, and `pdf` require an existing slides workspace containing `slide-*.html`.
75
+ On a fresh clone, the discovery commands (`--help`, `list-templates`, `list-styles`, and `preview-styles`) work without a deck. `edit`, `build-viewer`, `validate`, `convert`, and `pdf` require an existing slides workspace containing `slide-*.html`.
76
76
 
77
77
  ```bash
78
78
  slides-grab edit # Launch visual slide editor
@@ -88,9 +88,21 @@ slides-grab image --prompt "..." # Generate a local slide image with Nano Ban
88
88
  slides-grab fetch-video --url <youtube-url> --slides-dir decks/my-deck # Download a local video asset with yt-dlp
89
89
  slides-grab tldraw # Render a .tldr diagram into a slide-sized local SVG asset
90
90
  slides-grab list-templates # Show available slide templates
91
- slides-grab list-themes # Show available color themes
91
+ slides-grab list-styles # Show 35 bundled design styles (browse, preview, select)
92
+ slides-grab preview-styles # Open the 35-style visual gallery in browser
92
93
  ```
93
94
 
95
+ ## Design Style Collections
96
+
97
+ slides-grab bundles 35 design styles: 30 derived from [corazzon/pptx-design-styles](https://github.com/corazzon/pptx-design-styles) plus 5 slides-grab originals. Agents can also create fully custom designs beyond the bundled collection.
98
+
99
+ ```bash
100
+ slides-grab list-styles # Browse the catalog
101
+ slides-grab preview-styles # Local HTML preview
102
+ ```
103
+
104
+ Tell the agent which style to use (or ask for something custom) — no config files needed.
105
+
94
106
  ## Asset Contract
95
107
 
96
108
  Slides should store local image and video files in `<slides-dir>/assets/` and reference them as `./assets/<file>` from each `slide-XX.html`.
@@ -204,7 +216,7 @@ bin/ CLI entry point
204
216
  src/editor/ Visual editor (HTML + JS client modules)
205
217
  scripts/ Build, validate, convert, editor server
206
218
  templates/ Slide HTML templates (cover, content, chart, ...)
207
- themes/ Color themes (modern-dark, executive, sage, ...)
219
+ src/ Design styles data, style config, path resolution
208
220
  skills/ Shared Vercel-installable agent skills + references
209
221
  docs/ Installation & usage guides
210
222
  ```
package/bin/ppt-agent.js CHANGED
@@ -27,7 +27,7 @@ const figmaHelpText = [
27
27
 
28
28
  /**
29
29
  * Run a Node.js script from the package, with CWD set to the user's directory.
30
- * Scripts resolve slide paths via --slides-dir and templates/themes via src/resolve.js.
30
+ * Scripts resolve slide paths via --slides-dir and templates via src/resolve.js.
31
31
  */
32
32
  function runNodeScript(relativePath, args = []) {
33
33
  return new Promise((resolvePromise, rejectPromise) => {
@@ -68,6 +68,12 @@ function collectRepeatedOption(value, previous = []) {
68
68
  return [...previous, value];
69
69
  }
70
70
 
71
+ function reportCliError(error) {
72
+ console.error(`[slides-grab] ${error.message}`);
73
+ process.exitCode = 1;
74
+ }
75
+
76
+
71
77
  const program = new Command();
72
78
 
73
79
  program
@@ -224,7 +230,7 @@ program
224
230
  await runCommand('scripts/editor-server.js', args);
225
231
  });
226
232
 
227
- // --- Template/theme discovery commands ---
233
+ // --- Template/style discovery commands ---
228
234
 
229
235
  program
230
236
  .command('list-templates')
@@ -245,21 +251,42 @@ program
245
251
  });
246
252
 
247
253
  program
248
- .command('list-themes')
249
- .description('List all available color themes (local overrides + package built-ins)')
254
+ .command('list-styles')
255
+ .description('List bundled design styles agents and users can reference during slide generation')
250
256
  .action(async () => {
251
- const { listThemes } = await import('../src/resolve.js');
252
- const themes = listThemes();
253
- if (themes.length === 0) {
254
- console.log('No themes found.');
255
- return;
257
+ try {
258
+ const { listDesignStyles } = await import('../src/design-styles.js');
259
+ const styles = listDesignStyles();
260
+
261
+ if (styles.length === 0) {
262
+ console.log('No bundled design styles found.');
263
+ return;
264
+ }
265
+
266
+ console.log('Available design styles:\n');
267
+ for (const style of styles) {
268
+ console.log(` ${style.id.padEnd(22)} ${style.title}`);
269
+ console.log(` ${style.mood} · ${style.bestFor}`);
270
+ }
271
+
272
+ console.log(`\nTotal: ${styles.length} styles`);
273
+ console.log('Preview: slides-grab preview-styles [--style <id>]');
274
+ } catch (error) {
275
+ reportCliError(error);
256
276
  }
257
- console.log('Available themes:\n');
258
- for (const t of themes) {
259
- const tag = t.source === 'local' ? '(local)' : '(built-in)';
260
- console.log(` ${t.name.padEnd(20)} ${tag}`);
277
+ });
278
+
279
+ program
280
+ .command('preview-styles')
281
+ .description('Print the path to the bundled 35-style visual preview gallery')
282
+ .action(async () => {
283
+ try {
284
+ const { getPreviewHtmlPath } = await import('../src/design-styles.js');
285
+ const previewPath = getPreviewHtmlPath();
286
+ console.log(previewPath);
287
+ } catch (error) {
288
+ reportCliError(error);
261
289
  }
262
- console.log(`\nTotal: ${themes.length} themes`);
263
290
  });
264
291
 
265
292
  program
@@ -280,22 +307,5 @@ program
280
307
  console.log(content);
281
308
  });
282
309
 
283
- program
284
- .command('show-theme')
285
- .description('Print the contents of a theme file')
286
- .argument('<name>', 'Theme name (e.g. "modern-dark", "executive")')
287
- .action(async (name) => {
288
- const { resolveTheme } = await import('../src/resolve.js');
289
- const result = resolveTheme(name);
290
- if (!result) {
291
- console.error(`Theme "${name}" not found.`);
292
- process.exitCode = 1;
293
- return;
294
- }
295
- const content = readFileSync(result.path, 'utf-8');
296
- console.log(`/* Theme: ${name} (${result.source}) */`);
297
- console.log(`/* Path: ${result.path} */\n`);
298
- console.log(content);
299
- });
300
310
 
301
311
  await program.parseAsync(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slides-grab",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Agent-first presentation framework — plan, design, and visually edit HTML slides with Claude Code or Codex, then export to PDF or experimental/unstable PPTX/Figma formats",
5
5
  "license": "MIT",
6
6
  "author": "vkehfdl1",
@@ -45,7 +45,6 @@
45
45
  "skills/",
46
46
  "src/",
47
47
  "templates/",
48
- "themes/",
49
48
  "LICENSE",
50
49
  "README.md"
51
50
  ],
@@ -54,7 +53,7 @@
54
53
  "build-viewer": "node scripts/build-viewer.js",
55
54
  "validate": "node scripts/validate-slides.js",
56
55
  "convert": "node convert.cjs",
57
- "test": "node --test --test-concurrency=1 tests/editor/editor-codex-edit.test.js tests/nano-banana/nano-banana.test.js tests/pdf/html2pdf.test.js tests/pdf/html2pdf.e2e.test.js tests/figma/figma-export.test.js tests/image-contract/image-contract.test.js tests/tldraw/render-tldraw.test.js tests/validation/validate-slides.test.js tests/skills/installable-skills.test.js tests/video/download-video.test.js",
56
+ "test": "node --test --test-concurrency=1 tests/design/design-styles.test.js tests/editor/editor-codex-edit.test.js tests/editor/editor-server.test.js tests/nano-banana/nano-banana.test.js tests/pdf/html2pdf.test.js tests/pdf/html2pdf.e2e.test.js tests/figma/figma-export.test.js tests/image-contract/image-contract.test.js tests/tldraw/render-tldraw.test.js tests/validation/validate-slides.test.js tests/skills/installable-skills.test.js tests/video/download-video.test.js",
58
57
  "test:e2e": "node --test tests/editor/editor-ui.e2e.test.js tests/editor/editor-concurrency.e2e.test.js"
59
58
  },
60
59
  "dependencies": {
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { readdir, readFile, writeFile, mkdtemp, rm, mkdir } from 'node:fs/promises';
4
4
  import { watch as fsWatch } from 'node:fs';
5
+ import net from 'node:net';
5
6
  import { basename, dirname, join, resolve, relative, sep } from 'node:path';
6
7
  import { fileURLToPath } from 'node:url';
7
8
  import { tmpdir } from 'node:os';
@@ -45,6 +46,8 @@ const CODEX_MODELS = ['gpt-5.4', 'gpt-5.3-codex', 'gpt-5.3-codex-spark'];
45
46
  const ALL_MODELS = [...CODEX_MODELS, ...CLAUDE_MODELS];
46
47
  const DEFAULT_CODEX_MODEL = CODEX_MODELS[0];
47
48
  const SLIDE_FILE_PATTERN = /^slide-.*\.html$/i;
49
+ const PORT_PROBE_HOSTS = ['::', '127.0.0.1'];
50
+ const PORT_PROBE_IGNORED_CODES = new Set(['EAFNOSUPPORT', 'EADDRNOTAVAIL']);
48
51
 
49
52
  const MAX_RUNS = 200;
50
53
  const MAX_LOG_CHARS = 800_000;
@@ -117,6 +120,62 @@ function parseArgs(argv) {
117
120
  return opts;
118
121
  }
119
122
 
123
+ function buildPortInUseError(port) {
124
+ return new Error(`Editor port ${port} is already in use. Choose another port with \`--port <number>\` and try again.`);
125
+ }
126
+
127
+ async function assertHostPortAvailable(port, host) {
128
+ const probe = net.createServer();
129
+ try {
130
+ await new Promise((resolve, reject) => {
131
+ probe.once('error', reject);
132
+ probe.listen({ port, host, exclusive: true }, resolve);
133
+ });
134
+ } catch (error) {
135
+ if (error?.code === 'EADDRINUSE') {
136
+ throw buildPortInUseError(port);
137
+ }
138
+
139
+ if (PORT_PROBE_IGNORED_CODES.has(error?.code)) {
140
+ return;
141
+ }
142
+
143
+ throw error;
144
+ } finally {
145
+ if (probe.listening) {
146
+ await new Promise((resolve, reject) => {
147
+ probe.close((error) => {
148
+ if (error) {
149
+ reject(error);
150
+ return;
151
+ }
152
+ resolve();
153
+ });
154
+ });
155
+ }
156
+ }
157
+ }
158
+
159
+ async function assertPortUsable(port) {
160
+ for (const host of PORT_PROBE_HOSTS) {
161
+ await assertHostPortAvailable(port, host);
162
+ }
163
+ }
164
+
165
+ async function listenOnPort(app, port) {
166
+ return new Promise((resolve, reject) => {
167
+ const server = app.listen(port, () => resolve(server));
168
+ server.once('error', (error) => {
169
+ if (error?.code === 'EADDRINUSE') {
170
+ reject(buildPortInUseError(port));
171
+ return;
172
+ }
173
+
174
+ reject(error);
175
+ });
176
+ });
177
+ }
178
+
120
179
  const sseClients = new Set();
121
180
 
122
181
  function broadcastSSE(event, data) {
@@ -392,6 +451,7 @@ function createRunStore() {
392
451
  }
393
452
 
394
453
  async function startServer(opts) {
454
+ await assertPortUsable(opts.port);
395
455
  await loadDeps();
396
456
  const slidesDirectory = resolve(process.cwd(), opts.slidesDir);
397
457
  await mkdir(slidesDirectory, { recursive: true });
@@ -708,14 +768,14 @@ async function startServer(opts) {
708
768
  }, 300);
709
769
  });
710
770
 
711
- const server = app.listen(opts.port, () => {
712
- process.stdout.write('\n slides-grab editor\n');
713
- process.stdout.write(' ─────────────────────────────────────\n');
714
- process.stdout.write(` Local: http://localhost:${opts.port}\n`);
715
- process.stdout.write(` Models: ${ALL_MODELS.join(', ')}\n`);
716
- process.stdout.write(` Slides: ${slidesDirectory}\n`);
717
- process.stdout.write(' ─────────────────────────────────────\n\n');
718
- });
771
+ const server = await listenOnPort(app, opts.port);
772
+
773
+ process.stdout.write('\n slides-grab editor\n');
774
+ process.stdout.write(' ─────────────────────────────────────\n');
775
+ process.stdout.write(` Local: http://localhost:${opts.port}\n`);
776
+ process.stdout.write(` Models: ${ALL_MODELS.join(', ')}\n`);
777
+ process.stdout.write(` Slides: ${slidesDirectory}\n`);
778
+ process.stdout.write(' ─────────────────────────────────────\n\n');
719
779
 
720
780
  async function shutdown() {
721
781
  process.stdout.write('\n[editor] Shutting down...\n');
@@ -18,27 +18,28 @@ Guides you through the complete presentation pipeline from topic to exported fil
18
18
  Use the installed **slides-grab-plan** skill.
19
19
 
20
20
  1. Take user's topic, audience, and tone.
21
- 2. Create `slide-outline.md`.
22
- 3. Present outline to user.
23
- 4. Revise until user explicitly approves.
21
+ 2. **Style selection (mandatory before outline):** Run `slides-grab list-styles`, analyze the topic/tone, and shortlist 2–3 bundled styles that fit. Present the shortlist with reasons. Optionally offer `slides-grab preview-styles` for visual preview. If none of the 35 bundled styles fit, propose a fully custom visual direction. **Get explicit style approval before writing the outline.**
22
+ 3. Create `slide-outline.md` with the chosen style ID in the meta section (`style: <id>`).
23
+ 4. Present outline to user.
24
+ 5. Revise until user explicitly approves.
24
25
 
25
- **Do not proceed to Stage 2 without approval.**
26
+ **Do not proceed to Stage 2 without approval of both style and outline.**
26
27
 
27
28
  ### Stage 2 — Design
28
29
 
29
30
  Use the installed **slides-grab-design** skill.
30
31
 
31
- 1. Read approved `slide-outline.md`.
32
- 2. Generate `slide-*.html` files in the slides workspace (default: `slides/`).
33
- 3. Run validation: `slides-grab validate --slides-dir <path>`
34
- 4. If validation fails, automatically fix the slide HTML/CSS until validation passes.
35
- 5. For bespoke slide imagery, use `slides-grab image --prompt "<prompt>" --slides-dir <path>` so Nano Banana Pro saves a local asset under `<slides-dir>/assets/`.
36
- 6. For complex diagrams (architecture, workflows, relationship maps, multi-node concepts), prefer `tldraw` over hand-built HTML/CSS diagrams. Render the asset with `slides-grab tldraw`, store it under `<slides-dir>/assets/`, and place it in the slide with a normal `<img>`.
37
- 7. Keep local videos under `<slides-dir>/assets/`, prefer `poster="./assets/<file>"` thumbnails, and use `slides-grab fetch-video --url <youtube-url> --slides-dir <path>` (or `yt-dlp` directly) when the source starts on a supported web page.
38
- 8. If `GOOGLE_API_KEY` (or `GEMINI_API_KEY`) is unavailable or Nano Banana is down, ask the user for a Google API key or fall back to web search/download into `<slides-dir>/assets/`.
39
- 9. Launch the interactive editor for review: `slides-grab edit --slides-dir <path>`
40
- 10. Revise slides based on user feedback via the editor, then re-run validation after each edit round.
41
- 11. When the user confirms editing is complete, suggest next steps: build the viewer (`slides-grab build-viewer --slides-dir <path>`) for a final preview, or proceed directly to Stage 3 for PDF/PPTX export.
32
+ 1. Read approved `slide-outline.md` and apply the style specified in its meta section (`style: <id>`). Do not re-open style selection — the style was already approved in Stage 1.
33
+ 3. Generate `slide-*.html` files in the slides workspace (default: `slides/`).
34
+ 4. Run validation: `slides-grab validate --slides-dir <path>`
35
+ 5. If validation fails, automatically fix the slide HTML/CSS until validation passes.
36
+ 6. For bespoke slide imagery, use `slides-grab image --prompt "<prompt>" --slides-dir <path>` so Nano Banana Pro saves a local asset under `<slides-dir>/assets/`.
37
+ 7. For complex diagrams (architecture, workflows, relationship maps, multi-node concepts), prefer `tldraw` over hand-built HTML/CSS diagrams. Render the asset with `slides-grab tldraw`, store it under `<slides-dir>/assets/`, and place it in the slide with a normal `<img>`.
38
+ 8. Keep local videos under `<slides-dir>/assets/`, prefer `poster="./assets/<file>"` thumbnails, and use `slides-grab fetch-video --url <youtube-url> --slides-dir <path>` (or `yt-dlp` directly) when the source starts on a supported web page.
39
+ 9. If `GOOGLE_API_KEY` (or `GEMINI_API_KEY`) is unavailable or Nano Banana is down, ask the user for a Google API key or fall back to web search/download into `<slides-dir>/assets/`.
40
+ 10. Launch the interactive editor for review: `slides-grab edit --slides-dir <path>`
41
+ 11. Revise slides based on user feedback via the editor, then re-run validation after each edit round.
42
+ 12. When the user confirms editing is complete, suggest next steps: build the viewer (`slides-grab build-viewer --slides-dir <path>`) for a final preview, or proceed directly to Stage 3 for PDF/PPTX export.
42
43
 
43
44
  **Do not proceed to Stage 3 without approval.**
44
45
 
@@ -22,17 +22,18 @@ Use the installed **slides-grab-plan** skill.
22
22
  Use the installed **slides-grab-design** skill.
23
23
 
24
24
  1. Read approved `slide-outline.md`.
25
- 2. Generate `slide-*.html` files in the slides workspace (default: `slides/`).
26
- 3. Run validation: `slides-grab validate --slides-dir <path>`
27
- 4. If validation fails, automatically fix the slide HTML/CSS until validation passes.
28
- 5. Build the viewer: `slides-grab build-viewer --slides-dir <path>`
29
- 6. When a slide calls for bespoke imagery, prefer `slides-grab image --prompt "<prompt>" --slides-dir <path>` so Nano Banana Pro saves a local asset under `<slides-dir>/assets/`.
30
- 7. For complex diagrams (architecture, workflows, relationship maps, multi-node concepts), prefer `tldraw`. Render a local diagram asset with `slides-grab tldraw`, store it under `<slides-dir>/assets/`, and place it into the slide with a normal `<img>`.
31
- 8. Keep local videos under `<slides-dir>/assets/`, prefer `poster="./assets/<file>"` thumbnails, and use `slides-grab fetch-video --url <youtube-url> --slides-dir <path>` (or `yt-dlp` directly) when the source starts on a supported web page.
32
- 9. If `GOOGLE_API_KEY` or `GEMINI_API_KEY` is unavailable, or the Nano Banana API fails, ask the user for a Google API key or fall back to web search + download into `<slides-dir>/assets/`.
33
- 10. Present viewer to user for review.
34
- 11. Revise individual slides based on feedback, then re-run validation and rebuild the viewer.
35
- 12. Optionally launch the visual editor: `slides-grab edit --slides-dir <path>`
25
+ 2. If the user has not approved a visual direction yet, use `slides-grab list-styles` to shortlist bundled styles, optionally `slides-grab preview-styles` to open the visual gallery in browser, and agree on a direction with the user. If none of the 35 bundled styles fit, design a fully custom visual direction.
26
+ 3. Generate `slide-*.html` files in the slides workspace (default: `slides/`).
27
+ 4. Run validation: `slides-grab validate --slides-dir <path>`
28
+ 5. If validation fails, automatically fix the slide HTML/CSS until validation passes.
29
+ 6. Build the viewer: `slides-grab build-viewer --slides-dir <path>`
30
+ 7. When a slide calls for bespoke imagery, prefer `slides-grab image --prompt "<prompt>" --slides-dir <path>` so Nano Banana Pro saves a local asset under `<slides-dir>/assets/`.
31
+ 8. For complex diagrams (architecture, workflows, relationship maps, multi-node concepts), prefer `tldraw`. Render a local diagram asset with `slides-grab tldraw`, store it under `<slides-dir>/assets/`, and place it into the slide with a normal `<img>`.
32
+ 9. Keep local videos under `<slides-dir>/assets/`, prefer `poster="./assets/<file>"` thumbnails, and use `slides-grab fetch-video --url <youtube-url> --slides-dir <path>` (or `yt-dlp` directly) when the source starts on a supported web page.
33
+ 10. If `GOOGLE_API_KEY` or `GEMINI_API_KEY` is unavailable, or the Nano Banana API fails, ask the user for a Google API key or fall back to web search + download into `<slides-dir>/assets/`.
34
+ 11. Present viewer to user for review.
35
+ 12. Revise individual slides based on feedback, then re-run validation and rebuild the viewer.
36
+ 13. Optionally launch the visual editor: `slides-grab edit --slides-dir <path>`
36
37
 
37
38
  **Do not proceed to Stage 3 without approval.**
38
39
 
@@ -13,8 +13,7 @@ Use this after `slide-outline.md` is approved.
13
13
  Generate high-quality `slide-XX.html` files in the selected slides workspace (`slides/` by default) and support revision loops.
14
14
 
15
15
  ## Inputs
16
- - Approved `slide-outline.md`
17
- - Theme/layout preferences
16
+ - Approved `slide-outline.md` (must contain `style: <id>` in meta section — style was approved in Stage 1)
18
17
  - Requested edits per slide
19
18
 
20
19
  ## Outputs
@@ -22,20 +21,22 @@ Generate high-quality `slide-XX.html` files in the selected slides workspace (`s
22
21
  - Updated `<slides-dir>/viewer.html` via build script
23
22
 
24
23
  ## Workflow
25
- 1. Read approved `slide-outline.md`.
26
- 2. Before generating slides, write a quick **visual thesis** (mood/material/energy), a **content plan** (opener support/proof detail/story close/CTA), and the core design tokens (background, surface, text, muted, accent + display/headline/body/caption roles).
27
- 3. Generate slide HTML files with 2-digit numbering in selected `--slides-dir`.
28
- 4. When a slide explicitly needs bespoke imagery, when the user asks for an image, or when stronger imagery would materially improve the slide, prefer `slides-grab image --prompt "<prompt>" --slides-dir <path>` to generate a local asset with Nano Banana Pro and save it under `<slides-dir>/assets/`.
29
- 5. If the deck needs a complex diagram (architecture, workflows, relationship maps, multi-node concepts), create the diagram in `tldraw`, export it with `slides-grab tldraw`, and treat the result as a local slide asset under `<slides-dir>/assets/`.
30
- 6. If the slide needs a local video, store the video under `<slides-dir>/assets/`, reference it as `./assets/<file>`, and prefer a `poster="./assets/<file>"` thumbnail so PDF export uses a stable still image.
31
- 7. If the source video starts on YouTube or another supported page, use `slides-grab fetch-video --url <youtube-url> --slides-dir <path>` (or `yt-dlp` directly if needed) to download it into `<slides-dir>/assets/` before saving the slide HTML.
32
- 8. Run `slides-grab validate --slides-dir <path>` after generation or edits.
33
- 9. If validation fails, automatically fix the source slide HTML/CSS and re-run validation until it passes.
34
- 10. Run the slide litmus check from `references/beautiful-slide-defaults.md` before presenting the deck for review.
35
- 11. Launch the interactive editor for visual review: `slides-grab edit --slides-dir <path>`
36
- 12. Iterate on user feedback by editing only requested slide files, then re-run validation after each edit round.
37
- 13. When the user confirms editing is complete, suggest: build the viewer (`slides-grab build-viewer --slides-dir <path>`) for a final read-only preview, or proceed to export (PDF/PPTX).
38
- 14. Keep revising until user approves conversion stage.
24
+ 1. Read approved `slide-outline.md` and extract the `style` field from its meta section.
25
+ 2. Load the chosen style's full spec from `src/design-styles-data.js` colors, fonts, layout, signature elements, and things to avoid. If the meta specifies a custom direction instead of a bundled ID, use that custom direction as the design basis.
26
+ 3. Before generating slides, write a quick **visual thesis** (mood/material/energy), a **content plan** (opener → support/proof → detail/story → close/CTA), and the core design tokens (background, surface, text, muted, accent + display/headline/body/caption roles). Ground these tokens in the chosen style's spec.
27
+ 4. If you need to confirm or revisit the approved bundled style before designing, re-run `slides-grab list-styles` and open the gallery from `slides-grab preview-styles` so the Stage 2 deck stays aligned with the Stage 1 direction.
28
+ 5. Generate slide HTML files with 2-digit numbering in selected `--slides-dir`.
29
+ 6. When a slide explicitly needs bespoke imagery, when the user asks for an image, or when stronger imagery would materially improve the slide, prefer `slides-grab image --prompt "<prompt>" --slides-dir <path>` to generate a local asset with Nano Banana Pro and save it under `<slides-dir>/assets/`.
30
+ 7. If the deck needs a complex diagram (architecture, workflows, relationship maps, multi-node concepts), create the diagram in `tldraw`, export it with `slides-grab tldraw`, and treat the result as a local slide asset under `<slides-dir>/assets/`.
31
+ 8. If the slide needs a local video, store the video under `<slides-dir>/assets/`, reference it as `./assets/<file>`, and prefer a `poster="./assets/<file>"` thumbnail so PDF export uses a stable still image.
32
+ 9. If the source video starts on YouTube or another supported page, use `slides-grab fetch-video --url <youtube-url> --slides-dir <path>` (or `yt-dlp` directly if needed) to download it into `<slides-dir>/assets/` before saving the slide HTML.
33
+ 10. Run `slides-grab validate --slides-dir <path>` after generation or edits.
34
+ 11. If validation fails, automatically fix the source slide HTML/CSS and re-run validation until it passes.
35
+ 12. Run the slide litmus check from `references/beautiful-slide-defaults.md` before presenting the deck for review.
36
+ 13. Launch the interactive editor for visual review: `slides-grab edit --slides-dir <path>`
37
+ 14. Iterate on user feedback by editing only requested slide files, then re-run validation after each edit round.
38
+ 15. When the user confirms editing is complete, suggest: build the viewer (`slides-grab build-viewer --slides-dir <path>`) for a final read-only preview, or proceed to export (PDF/PPTX).
39
+ 16. Keep revising until user approves conversion stage.
39
40
 
40
41
  ## Rules
41
42
  - Keep slide size 720pt x 405pt.
@@ -9,6 +9,8 @@ These are the packaged design rules for installable `slides-grab` skills.
9
9
  - Generate a bespoke image asset: `slides-grab image --prompt "<prompt>" --slides-dir <path>`
10
10
  - Download a web video into slide assets: `slides-grab fetch-video --url <youtube-url> --slides-dir <path>`
11
11
  - Render `tldraw` diagrams: `slides-grab tldraw --input <path> --output <path>`
12
+ - List bundled design collections: `slides-grab list-styles`
13
+ - Open the visual style gallery in browser: `slides-grab preview-styles`
12
14
 
13
15
  ## Slide spec
14
16
  - Slide size: `720pt x 405pt` (16:9)
@@ -30,13 +32,6 @@ These are the packaged design rules for installable `slides-grab` skills.
30
32
  - Do not leave remote `http(s)://` image URLs in saved slide HTML
31
33
  - Never use absolute filesystem paths
32
34
 
33
- ## Package-published theme references
34
- - `themes/executive.css`
35
- - `themes/sage.css`
36
- - `themes/modern-dark.css`
37
- - `themes/corporate.css`
38
- - `themes/warm.css`
39
-
40
35
  ## Package-published template references
41
36
  - `templates/cover.html`
42
37
  - `templates/contents.html`
@@ -52,8 +47,12 @@ These are the packaged design rules for installable `slides-grab` skills.
52
47
  - `templates/diagram.html`
53
48
  - `templates/diagram-tldraw.html`
54
49
  - `templates/custom/`
50
+ - `templates/design-styles/README.md` — bundled design collection reference derived from `corazzon/pptx-design-styles`
51
+ - `templates/design-styles/preview.html` — visual gallery of all 35 styles (open with `slides-grab preview-styles`)
52
+ - `src/design-styles-data.js` — full style specs (colors, fonts, layout, signature elements, things to avoid) for all 35 bundled styles; read this after the user picks a style to ground your design tokens
55
53
 
56
54
  ## Review loop
55
+ - The design style is chosen in Stage 1 (Plan) and recorded in `slide-outline.md`'s meta section (`style: <id>`). Do not re-open style selection in Stage 2 — read and apply the already-approved style.
57
56
  - Generate or edit only the needed slide files.
58
57
  - Prefer `slides-grab image` before remote image sourcing when the slide needs bespoke imagery.
59
58
  - Prefer `tldraw` for complex diagrams instead of hand-building dense diagram geometry in HTML/CSS.
@@ -97,27 +97,15 @@ line-height: 1;
97
97
 
98
98
  ## Color Palette System
99
99
 
100
- ### 1. Executive Minimal (Recommended Default)
101
- Refined business presentation look
102
- - File: `themes/executive.css`
100
+ All color palettes are now bundled as design styles accessible via `slides-grab list-styles`. The five original palettes are styles 31–35:
103
101
 
104
- ### 2. Sage Professional
105
- Calm and trustworthy tone
106
- - File: `themes/sage.css`
102
+ - **executive-minimal** Refined business (warm white + black accent)
103
+ - **sage-professional** — Calm and trustworthy (sage green tones)
104
+ - **modern-dark** — High-impact dark (pure dark + white text)
105
+ - **corporate-blue** — Traditional business (white + blue accent)
106
+ - **warm-neutral** — Warm and approachable (cream + terracotta)
107
107
 
108
- ### 3. Modern Dark
109
- High-impact dark theme
110
- - File: `themes/modern-dark.css`
111
-
112
- ### 4. Corporate Blue
113
- Traditional business tone
114
- - File: `themes/corporate.css`
115
-
116
- ### 5. Warm Neutral
117
- Warm and approachable tone
118
- - File: `themes/warm.css`
119
-
120
- Theme files use shared CSS variables (`:root`). Copy a theme file to create a custom theme.
108
+ Run `slides-grab list-styles` to browse all 35 bundled styles, or design a fully custom palette when none fit.
121
109
 
122
110
  ---
123
111
 
@@ -36,7 +36,7 @@
36
36
  - Do not persist runtime-only editor/viewer injections in saved slide HTML.
37
37
 
38
38
  ## Important Notes
39
- - CSS gradients are not supported in PowerPoint conversion; replace them with background images.
39
+ - CSS gradients may not export cleanly to all formats; prefer solid colors or background images when possible.
40
40
  - Always include the Pretendard CDN link.
41
41
  - Use `./assets/<file>` from each `slide-XX.html` for local images and videos, and avoid absolute filesystem paths.
42
42
  - Always include `#` prefix in CSS colors.
@@ -19,17 +19,19 @@ Produce an approved `slide-outline.md` before any slide HTML generation.
19
19
  - Optional research findings
20
20
 
21
21
  ## Output
22
- - `slide-outline.md`
22
+ - `slide-outline.md` (must include `style: <id>` in meta section)
23
23
 
24
24
  ## Workflow
25
25
  1. Analyze user goal and audience.
26
- 2. Create or revise `slide-outline.md` with ordered slides and key messages.
27
- 3. Present a concise summary to user.
28
- 4. Repeat revisions until explicit approval.
26
+ 2. **Style selection (mandatory, before outline):** Run `slides-grab list-styles`, shortlist 2–3 styles that match the topic/tone, present the shortlist with reasons, and get explicit user approval. Optionally offer `slides-grab preview-styles` for visual preview. If no bundled style fits, propose a custom direction and get approval.
27
+ 3. Create or revise `slide-outline.md` with ordered slides and key messages. Record the approved style ID in the meta section (`style: <id>`).
28
+ 4. Present a concise summary to user.
29
+ 5. Repeat revisions until explicit approval.
29
30
 
30
31
  ## Rules
32
+ - **Do not write the outline before the user approves a style.** Style selection comes first.
31
33
  - Do not generate slide HTML (`<slides-dir>/slide-*.html`) in this stage.
32
- - Keep scope to structure and narrative.
34
+ - Keep scope to structure, narrative, and style selection.
33
35
  - Ask for approval before moving to design.
34
36
  - Assume later stages run through the packaged `slides-grab` CLI.
35
37
  - Use the packaged CLI and bundled references only; do not depend on unpublished agent-specific files.