slides-grab 1.1.5 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/bin/ppt-agent.js +22 -0
- package/package.json +7 -3
- package/scripts/editor-server.js +30 -61
- package/scripts/render-tldraw.js +44 -0
- package/skills/slides-grab/SKILL.md +5 -3
- package/skills/slides-grab/references/presentation-workflow-reference.md +5 -3
- package/skills/slides-grab-design/SKILL.md +17 -7
- package/skills/slides-grab-design/references/beautiful-slide-defaults.md +45 -0
- package/skills/slides-grab-design/references/design-rules.md +6 -0
- package/skills/slides-grab-design/references/design-system-full.md +17 -9
- package/skills/slides-grab-design/references/detailed-design-rules.md +3 -1
- package/src/editor/codex-edit.js +165 -15
- package/src/editor/edit-subprocess.js +97 -0
- package/src/image-contract.js +6 -6
- package/src/tldraw/render.js +470 -0
- package/src/validation/core.js +4 -0
- package/templates/diagram-tldraw.html +56 -0
package/README.md
CHANGED
|
@@ -82,6 +82,7 @@ slides-grab figma # Export an experimental / unstable Figma Slides i
|
|
|
82
82
|
slides-grab pdf # Export PDF in capture mode (default)
|
|
83
83
|
slides-grab pdf --resolution 2160p # Higher-resolution image-backed PDF export
|
|
84
84
|
slides-grab pdf --mode print # Export searchable/selectable text PDF
|
|
85
|
+
slides-grab tldraw # Render a .tldr diagram into a slide-sized local SVG asset
|
|
85
86
|
slides-grab list-templates # Show available slide templates
|
|
86
87
|
slides-grab list-themes # Show available color themes
|
|
87
88
|
```
|
|
@@ -116,6 +117,27 @@ slides-grab figma --slides-dir decks/my-deck --output decks/my-deck-figma.p
|
|
|
116
117
|
|
|
117
118
|
> **Warning:** `slides-grab convert` and `slides-grab figma` are currently **experimental / unstable**. Expect best-effort output, layout shifts, and manual cleanup in PowerPoint or Figma.
|
|
118
119
|
|
|
120
|
+
### Tldraw Diagram Assets
|
|
121
|
+
|
|
122
|
+
Use `slides-grab tldraw` when you want a newly authored `tldraw` diagram to fit an exact slide region and remain export-friendly as a local SVG asset. The command supports current-format `.tldr` files and store-snapshot JSON; legacy pre-records `.tldr` files must be reopened and resaved in a current `tldraw` build first:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
slides-grab tldraw \
|
|
126
|
+
--input decks/my-deck/assets/system.tldr \
|
|
127
|
+
--output decks/my-deck/assets/system.svg \
|
|
128
|
+
--width 640 \
|
|
129
|
+
--height 320 \
|
|
130
|
+
--padding 16
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Then reference the generated SVG from your slide HTML with a normal local image:
|
|
134
|
+
|
|
135
|
+
```html
|
|
136
|
+
<img src="./assets/system.svg" alt="System architecture diagram">
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The built-in `diagram-tldraw` template is a simple starting point for this workflow.
|
|
140
|
+
|
|
119
141
|
### Figma Workflow
|
|
120
142
|
|
|
121
143
|
```bash
|
package/bin/ppt-agent.js
CHANGED
|
@@ -154,6 +154,28 @@ program
|
|
|
154
154
|
await runCommand('scripts/figma-export.js', args);
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
+
program
|
|
158
|
+
.command('tldraw')
|
|
159
|
+
.description('Render a current-format .tldr or store-snapshot JSON file to an exact-size SVG asset for slides')
|
|
160
|
+
.option('--input <path>', 'Input current-format .tldr or snapshot JSON file')
|
|
161
|
+
.option('--output <path>', 'Output SVG asset path')
|
|
162
|
+
.option('--width <number>', 'Exact output width in CSS pixels')
|
|
163
|
+
.option('--height <number>', 'Exact output height in CSS pixels')
|
|
164
|
+
.option('--padding <number>', 'Inner fit padding in CSS pixels')
|
|
165
|
+
.option('--background <css>', 'Optional wrapper background fill')
|
|
166
|
+
.option('--page-id <id>', 'Optional tldraw page id to export')
|
|
167
|
+
.action(async (options = {}) => {
|
|
168
|
+
const args = [];
|
|
169
|
+
if (options.input) args.push('--input', String(options.input));
|
|
170
|
+
if (options.output) args.push('--output', String(options.output));
|
|
171
|
+
if (options.width) args.push('--width', String(options.width));
|
|
172
|
+
if (options.height) args.push('--height', String(options.height));
|
|
173
|
+
if (options.padding) args.push('--padding', String(options.padding));
|
|
174
|
+
if (options.background) args.push('--background', String(options.background));
|
|
175
|
+
if (options.pageId) args.push('--page-id', String(options.pageId));
|
|
176
|
+
await runCommand('scripts/render-tldraw.js', args);
|
|
177
|
+
});
|
|
178
|
+
|
|
157
179
|
program
|
|
158
180
|
.command('edit')
|
|
159
181
|
.description('Start interactive slide editor with Codex image-based edit flow')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slides-grab",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
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",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"scripts/figma-export.js",
|
|
39
39
|
"scripts/html2pdf.js",
|
|
40
40
|
"scripts/html2pptx.js",
|
|
41
|
+
"scripts/render-tldraw.js",
|
|
41
42
|
"scripts/validate-slides.js",
|
|
42
43
|
"skills/",
|
|
43
44
|
"src/",
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
"build-viewer": "node scripts/build-viewer.js",
|
|
52
53
|
"validate": "node scripts/validate-slides.js",
|
|
53
54
|
"convert": "node convert.cjs",
|
|
54
|
-
"test": "node --test tests/editor/editor-codex-edit.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/validation/validate-slides.test.js tests/skills/installable-skills.test.js",
|
|
55
|
+
"test": "node --test tests/editor/editor-codex-edit.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",
|
|
55
56
|
"test:e2e": "node --test tests/editor/editor-ui.e2e.test.js tests/editor/editor-concurrency.e2e.test.js"
|
|
56
57
|
},
|
|
57
58
|
"dependencies": {
|
|
@@ -60,7 +61,10 @@
|
|
|
60
61
|
"pdf-lib": "^1.17.1",
|
|
61
62
|
"playwright": "^1.40.0",
|
|
62
63
|
"pptxgenjs": "^3.12.0",
|
|
64
|
+
"react": "^19.2.4",
|
|
65
|
+
"react-dom": "^19.2.4",
|
|
63
66
|
"react-icons": "^5.0.0",
|
|
64
|
-
"sharp": "^0.33.0"
|
|
67
|
+
"sharp": "^0.33.0",
|
|
68
|
+
"tldraw": "^4.4.1"
|
|
65
69
|
}
|
|
66
70
|
}
|
package/scripts/editor-server.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import { readdir, readFile, writeFile, mkdtemp, rm, mkdir } from 'node:fs/promises';
|
|
4
4
|
import { watch as fsWatch } from 'node:fs';
|
|
5
5
|
import { basename, dirname, join, resolve, relative, sep } from 'node:path';
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
7
6
|
import { fileURLToPath } from 'node:url';
|
|
8
7
|
import { tmpdir } from 'node:os';
|
|
9
8
|
|
|
@@ -18,6 +17,10 @@ import {
|
|
|
18
17
|
scaleSelectionToScreenshot,
|
|
19
18
|
writeAnnotatedScreenshot,
|
|
20
19
|
} from '../src/editor/codex-edit.js';
|
|
20
|
+
import {
|
|
21
|
+
parseEditTimeoutMs,
|
|
22
|
+
runEditSubprocess,
|
|
23
|
+
} from '../src/editor/edit-subprocess.js';
|
|
21
24
|
import { buildSlideRuntimeHtml } from '../src/image-contract.js';
|
|
22
25
|
|
|
23
26
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -45,6 +48,7 @@ const SLIDE_FILE_PATTERN = /^slide-.*\.html$/i;
|
|
|
45
48
|
|
|
46
49
|
const MAX_RUNS = 200;
|
|
47
50
|
const MAX_LOG_CHARS = 800_000;
|
|
51
|
+
const EDIT_TIMEOUT_MS = parseEditTimeoutMs();
|
|
48
52
|
|
|
49
53
|
function printUsage() {
|
|
50
54
|
process.stdout.write(`Usage: slides-grab edit [options]\n\n`);
|
|
@@ -233,37 +237,24 @@ function randomRunId() {
|
|
|
233
237
|
return `run-${ts}-${rand}`;
|
|
234
238
|
}
|
|
235
239
|
|
|
240
|
+
function mirrorRunLog(onLog) {
|
|
241
|
+
return (stream, chunk) => {
|
|
242
|
+
onLog(stream, chunk);
|
|
243
|
+
process[stream].write(chunk);
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
236
247
|
function spawnCodexEdit({ prompt, imagePath, model, cwd, onLog }) {
|
|
237
248
|
const codexBin = process.env.PPT_AGENT_CODEX_BIN || 'codex';
|
|
238
249
|
const args = buildCodexExecArgs({ prompt, imagePath, model });
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const text = chunk.toString();
|
|
248
|
-
stdout += text;
|
|
249
|
-
onLog('stdout', text);
|
|
250
|
-
process.stdout.write(text);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
child.stderr.on('data', (chunk) => {
|
|
254
|
-
const text = chunk.toString();
|
|
255
|
-
stderr += text;
|
|
256
|
-
onLog('stderr', text);
|
|
257
|
-
process.stderr.write(text);
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
child.on('close', (code) => {
|
|
261
|
-
resolvePromise({ code: code ?? 1, stdout, stderr });
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
child.on('error', (error) => {
|
|
265
|
-
rejectPromise(error);
|
|
266
|
-
});
|
|
250
|
+
return runEditSubprocess({
|
|
251
|
+
bin: codexBin,
|
|
252
|
+
args,
|
|
253
|
+
cwd,
|
|
254
|
+
stdio: 'pipe',
|
|
255
|
+
timeoutMs: EDIT_TIMEOUT_MS,
|
|
256
|
+
engineLabel: 'Codex',
|
|
257
|
+
onLog: mirrorRunLog(onLog),
|
|
267
258
|
});
|
|
268
259
|
}
|
|
269
260
|
|
|
@@ -275,37 +266,15 @@ function spawnClaudeEdit({ prompt, imagePath, model, cwd, onLog }) {
|
|
|
275
266
|
const env = { ...process.env };
|
|
276
267
|
delete env.CLAUDECODE;
|
|
277
268
|
|
|
278
|
-
return
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
child.stdout.on('data', (chunk) => {
|
|
289
|
-
const text = chunk.toString();
|
|
290
|
-
stdout += text;
|
|
291
|
-
onLog('stdout', text);
|
|
292
|
-
process.stdout.write(text);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
child.stderr.on('data', (chunk) => {
|
|
296
|
-
const text = chunk.toString();
|
|
297
|
-
stderr += text;
|
|
298
|
-
onLog('stderr', text);
|
|
299
|
-
process.stderr.write(text);
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
child.on('close', (code) => {
|
|
303
|
-
resolvePromise({ code: code ?? 1, stdout, stderr });
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
child.on('error', (error) => {
|
|
307
|
-
rejectPromise(error);
|
|
308
|
-
});
|
|
269
|
+
return runEditSubprocess({
|
|
270
|
+
bin: claudeBin,
|
|
271
|
+
args,
|
|
272
|
+
cwd,
|
|
273
|
+
env,
|
|
274
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
275
|
+
timeoutMs: EDIT_TIMEOUT_MS,
|
|
276
|
+
engineLabel: 'Claude',
|
|
277
|
+
onLog: mirrorRunLog(onLog),
|
|
309
278
|
});
|
|
310
279
|
}
|
|
311
280
|
|
|
@@ -674,7 +643,7 @@ async function startServer(opts) {
|
|
|
674
643
|
const success = result.code === 0;
|
|
675
644
|
const message = success
|
|
676
645
|
? `${engineLabel} edit completed.`
|
|
677
|
-
: `${engineLabel} exited with code ${result.code}
|
|
646
|
+
: (result.timeoutMessage || `${engineLabel} exited with code ${result.code}.`);
|
|
678
647
|
|
|
679
648
|
runStore.finishRun(runId, {
|
|
680
649
|
status: success ? 'success' : 'failed',
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
buildFixedSizeSvg,
|
|
8
|
+
buildTldrawImportUrl,
|
|
9
|
+
DEFAULT_TLDRAW_HEIGHT,
|
|
10
|
+
DEFAULT_TLDRAW_OUTPUT,
|
|
11
|
+
DEFAULT_TLDRAW_PADDING,
|
|
12
|
+
DEFAULT_TLDRAW_WIDTH,
|
|
13
|
+
getTldrawUsage,
|
|
14
|
+
loadTldrawInput,
|
|
15
|
+
main,
|
|
16
|
+
normalizeTldrawSnapshot,
|
|
17
|
+
parseTldrawCliArgs,
|
|
18
|
+
renderTldrawFile,
|
|
19
|
+
renderTldrawSnapshot,
|
|
20
|
+
} from '../src/tldraw/render.js';
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
buildFixedSizeSvg,
|
|
24
|
+
buildTldrawImportUrl,
|
|
25
|
+
DEFAULT_TLDRAW_HEIGHT,
|
|
26
|
+
DEFAULT_TLDRAW_OUTPUT,
|
|
27
|
+
DEFAULT_TLDRAW_PADDING,
|
|
28
|
+
DEFAULT_TLDRAW_WIDTH,
|
|
29
|
+
getTldrawUsage,
|
|
30
|
+
loadTldrawInput,
|
|
31
|
+
normalizeTldrawSnapshot,
|
|
32
|
+
parseTldrawCliArgs,
|
|
33
|
+
renderTldrawFile,
|
|
34
|
+
renderTldrawSnapshot,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const isMain = process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
38
|
+
|
|
39
|
+
if (isMain) {
|
|
40
|
+
main().catch((error) => {
|
|
41
|
+
console.error(`[slides-grab] ${error.message}`);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -33,9 +33,10 @@ Use the installed **slides-grab-design** skill.
|
|
|
33
33
|
3. Run validation: `slides-grab validate --slides-dir <path>`
|
|
34
34
|
4. If validation fails, automatically fix the slide HTML/CSS until validation passes.
|
|
35
35
|
5. Build the viewer: `slides-grab build-viewer --slides-dir <path>`
|
|
36
|
-
6.
|
|
37
|
-
7.
|
|
38
|
-
8.
|
|
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. Present viewer to user for review.
|
|
38
|
+
8. Revise individual slides based on feedback, then re-run validation and rebuild the viewer.
|
|
39
|
+
9. Optionally launch the visual editor: `slides-grab edit --slides-dir <path>`
|
|
39
40
|
|
|
40
41
|
**Do not proceed to Stage 3 without approval.**
|
|
41
42
|
|
|
@@ -58,6 +59,7 @@ Use the installed **slides-grab-export** skill.
|
|
|
58
59
|
4. **Use `decks/<deck-name>/`** as the slides workspace for multi-deck projects.
|
|
59
60
|
5. **Call out export risk clearly**: PPTX and Figma export are experimental / unstable and must be described as best-effort output.
|
|
60
61
|
6. Use the stage skills as the source of truth for plan, design, and export rules.
|
|
62
|
+
7. When a slide needs a complex diagram, default to a `tldraw`-generated asset unless the user explicitly asks for a different approach.
|
|
61
63
|
|
|
62
64
|
## Reference
|
|
63
65
|
- `references/presentation-workflow-reference.md` — archived end-to-end workflow guidance from the legacy skill set
|
|
@@ -26,9 +26,10 @@ Use **design-skill** (`.claude/skills/design-skill/SKILL.md`).
|
|
|
26
26
|
3. Run validation: `slides-grab validate --slides-dir <path>`
|
|
27
27
|
4. If validation fails, automatically fix the slide HTML/CSS until validation passes.
|
|
28
28
|
5. Build the viewer: `node scripts/build-viewer.js --slides-dir <path>`
|
|
29
|
-
6.
|
|
30
|
-
7.
|
|
31
|
-
8.
|
|
29
|
+
6. 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>`.
|
|
30
|
+
7. Present viewer to user for review.
|
|
31
|
+
8. Revise individual slides based on feedback, then re-run validation and rebuild the viewer.
|
|
32
|
+
9. Optionally launch the visual editor: `slides-grab edit --slides-dir <path>`
|
|
32
33
|
|
|
33
34
|
**Do not proceed to Stage 3 without approval.**
|
|
34
35
|
|
|
@@ -50,3 +51,4 @@ Use **pptx-skill** (`.claude/skills/pptx-skill/SKILL.md`).
|
|
|
50
51
|
3. **Read each stage's SKILL.md** for detailed rules — this skill only orchestrates.
|
|
51
52
|
4. **Use `decks/<deck-name>/`** as the slides workspace for multi-deck projects.
|
|
52
53
|
5. **Call out export risk clearly**: PPTX and Figma export are experimental / unstable and should be described as best-effort output.
|
|
54
|
+
6. **Prefer tldraw for complex diagrams**: Use `slides-grab tldraw` for diagram-heavy slides unless the user explicitly wants another rendering path.
|
|
@@ -23,20 +23,29 @@ Generate high-quality `slide-XX.html` files in the selected slides workspace (`s
|
|
|
23
23
|
|
|
24
24
|
## Workflow
|
|
25
25
|
1. Read approved `slide-outline.md`.
|
|
26
|
-
2.
|
|
27
|
-
3.
|
|
28
|
-
4. If
|
|
29
|
-
5. Run `slides-grab
|
|
30
|
-
6.
|
|
31
|
-
7.
|
|
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. 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/`.
|
|
29
|
+
5. Run `slides-grab validate --slides-dir <path>` after generation or edits.
|
|
30
|
+
6. If validation fails, automatically fix the source slide HTML/CSS and re-run validation until it passes.
|
|
31
|
+
7. Run `slides-grab build-viewer --slides-dir <path>` only after validation passes.
|
|
32
|
+
8. Run the slide litmus check from `references/beautiful-slide-defaults.md` before presenting the deck for review.
|
|
33
|
+
9. Iterate on user feedback by editing only requested slide files, then re-run validation and rebuild the viewer.
|
|
34
|
+
10. Keep revising until user approves conversion stage.
|
|
32
35
|
|
|
33
36
|
## Rules
|
|
34
37
|
- Keep slide size 720pt x 405pt.
|
|
35
38
|
- Keep semantic text tags (`p`, `h1-h6`, `ul`, `ol`, `li`).
|
|
36
39
|
- Put local images under `<slides-dir>/assets/` and reference them as `./assets/<file>`.
|
|
37
40
|
- Allow `data:` URLs when the slide must be fully self-contained.
|
|
38
|
-
-
|
|
41
|
+
- Do not leave remote `http(s)://` image URLs in saved slide HTML; download source images into `<slides-dir>/assets/` and reference them as `./assets/<file>`.
|
|
39
42
|
- Prefer `<img>` for slide imagery and `data-image-placeholder` when no final asset exists.
|
|
43
|
+
- Default to one job per slide, one dominant visual anchor, and copy that scans in seconds.
|
|
44
|
+
- Treat opening slides and section dividers like posters, not dashboards.
|
|
45
|
+
- Default to cardless layouts; only add a card when it improves structure or comprehension.
|
|
46
|
+
- Use whitespace, alignment, scale, cropping, and contrast before adding decorative chrome.
|
|
47
|
+
- Prefer `tldraw` for complex diagrams instead of recreating dense node/edge diagrams directly in HTML/CSS.
|
|
48
|
+
- Use `slides-grab tldraw` plus `templates/diagram-tldraw.html` when that gives a cleaner, more export-friendly result.
|
|
40
49
|
- Do not present slides for review until `slides-grab validate --slides-dir <path>` passes.
|
|
41
50
|
- Do not start conversion before approval.
|
|
42
51
|
- Use the packaged CLI and bundled references only; do not depend on unpublished agent-specific files.
|
|
@@ -45,4 +54,5 @@ Generate high-quality `slide-XX.html` files in the selected slides workspace (`s
|
|
|
45
54
|
For full constraints and style system, follow:
|
|
46
55
|
- `references/design-rules.md`
|
|
47
56
|
- `references/detailed-design-rules.md`
|
|
57
|
+
- `references/beautiful-slide-defaults.md` — slide-specific art direction defaults adapted from OpenAI's frontend design guidance
|
|
48
58
|
- `references/design-system-full.md` — archived full design system, templates, and advanced pattern guidance
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Beautiful Slide Defaults
|
|
2
|
+
|
|
3
|
+
Slide-specific art direction guidance adapted from OpenAI's frontend design guidance for GPT-5.4. Use it to make HTML slides feel deliberate, premium, and instantly scannable without breaking `slides-grab`'s export constraints.
|
|
4
|
+
|
|
5
|
+
## Working Model
|
|
6
|
+
|
|
7
|
+
Before building the deck, write two things:
|
|
8
|
+
|
|
9
|
+
- **visual thesis** — one sentence describing the mood, material, energy, and imagery treatment
|
|
10
|
+
- **content plan** — opener → support/proof → detail/story → close/CTA or decision
|
|
11
|
+
|
|
12
|
+
If the style direction is still open, gather visual references or a mood board first. Define the core tokens early: `background`, `surface`, `primary text`, `muted text`, `accent`, plus typography roles for `display`, `headline`, `body`, and `caption`.
|
|
13
|
+
|
|
14
|
+
## Beautiful Defaults for Slides
|
|
15
|
+
|
|
16
|
+
- Start with composition, not components.
|
|
17
|
+
- Treat the opening slide like a poster and make the title or brand the loudest text.
|
|
18
|
+
- Give each slide one job, one primary takeaway, and one dominant visual anchor.
|
|
19
|
+
- Keep copy short enough to scan in seconds.
|
|
20
|
+
- Use whitespace, alignment, scale, cropping, and contrast before adding chrome.
|
|
21
|
+
- Limit the system by default: two typefaces max and one accent color.
|
|
22
|
+
- Default to cardless layouts. Prefer sections, grids, media blocks, dividers, and strong negative space.
|
|
23
|
+
- Use real imagery, product views, diagrams, or data as the main visual idea. Decorative gradients and abstract filler do not count.
|
|
24
|
+
- Keep the first slide free of secondary clutter such as stat strips, metadata piles, or multiple competing callouts unless the brief explicitly demands them.
|
|
25
|
+
|
|
26
|
+
## Narrative Sequence for Decks
|
|
27
|
+
|
|
28
|
+
Use a narrative rhythm that feels intentional:
|
|
29
|
+
|
|
30
|
+
1. **Opener** — identity, premise, or promise
|
|
31
|
+
2. **Support / proof** — key evidence, context, or concrete value
|
|
32
|
+
3. **Detail / story** — workflow, mechanism, or deeper explanation
|
|
33
|
+
4. **Close / CTA** — decision, recommendation, next step, or final message
|
|
34
|
+
|
|
35
|
+
Section dividers should reset the visual tempo. Alternate dense proof slides with simpler image-led or statement-led slides so the deck keeps breathing.
|
|
36
|
+
|
|
37
|
+
## Review Litmus
|
|
38
|
+
|
|
39
|
+
Before showing the deck, ask:
|
|
40
|
+
|
|
41
|
+
- Can the audience grasp the main point of each slide in 3–5 seconds?
|
|
42
|
+
- Does each slide have one dominant idea instead of multiple competing blocks?
|
|
43
|
+
- Is there one real visual anchor, not just decoration?
|
|
44
|
+
- Would this still feel premium without shadows, cards, or extra chrome?
|
|
45
|
+
- Can any line of copy, badge, or callout be removed without losing meaning?
|
|
@@ -6,6 +6,7 @@ These are the packaged design rules for installable `slides-grab` skills.
|
|
|
6
6
|
- Validate slides: `slides-grab validate --slides-dir <path>`
|
|
7
7
|
- Build review viewer: `slides-grab build-viewer --slides-dir <path>`
|
|
8
8
|
- Launch editor: `slides-grab edit --slides-dir <path>`
|
|
9
|
+
- Render `tldraw` diagrams: `slides-grab tldraw --input <path> --output <path>`
|
|
9
10
|
|
|
10
11
|
## Slide spec
|
|
11
12
|
- Slide size: `720pt x 405pt` (16:9)
|
|
@@ -17,7 +18,10 @@ These are the packaged design rules for installable `slides-grab` skills.
|
|
|
17
18
|
## Asset rules
|
|
18
19
|
- Store deck-local assets in `<slides-dir>/assets/`
|
|
19
20
|
- Reference deck-local assets as `./assets/<file>`
|
|
21
|
+
- If an image comes from the web, download it into `<slides-dir>/assets/` before referencing it
|
|
22
|
+
- Use `tldraw`-generated local assets for complex diagrams when possible
|
|
20
23
|
- Allow `data:` URLs only when the slide must be fully self-contained
|
|
24
|
+
- Do not leave remote `http(s)://` image URLs in saved slide HTML
|
|
21
25
|
- Never use absolute filesystem paths
|
|
22
26
|
|
|
23
27
|
## Package-published theme references
|
|
@@ -40,10 +44,12 @@ These are the packaged design rules for installable `slides-grab` skills.
|
|
|
40
44
|
- `templates/closing.html`
|
|
41
45
|
- `templates/chart.html`
|
|
42
46
|
- `templates/diagram.html`
|
|
47
|
+
- `templates/diagram-tldraw.html`
|
|
43
48
|
- `templates/custom/`
|
|
44
49
|
|
|
45
50
|
## Review loop
|
|
46
51
|
- Generate or edit only the needed slide files.
|
|
52
|
+
- Prefer `tldraw` for complex diagrams instead of hand-building dense diagram geometry in HTML/CSS.
|
|
47
53
|
- Re-run validation after every generation/edit pass.
|
|
48
54
|
- Rebuild the viewer only after validation passes.
|
|
49
55
|
- Do not move to export until the user approves the reviewed deck.
|
|
@@ -282,6 +282,10 @@ grid-template-columns: 1fr 2.3fr;
|
|
|
282
282
|
### 12. Diagram Slide
|
|
283
283
|
- Template file: `templates/diagram.html`
|
|
284
284
|
|
|
285
|
+
### 13. Tldraw Diagram Slide
|
|
286
|
+
- Template file: `templates/diagram-tldraw.html`
|
|
287
|
+
- Use this when the slide needs a complex diagram that will be easier to author in `tldraw` and safer to export as a local image asset.
|
|
288
|
+
|
|
285
289
|
### Custom Templates
|
|
286
290
|
- Custom template directory: `templates/custom/`
|
|
287
291
|
- Users can add template files as drop-in for reuse.
|
|
@@ -457,11 +461,13 @@ Store the image at `<slides-dir>/assets/team-photo.png`.
|
|
|
457
461
|
<img src="data:image/svg+xml;base64,..." alt="Illustration" style="width: 220pt; height: 140pt; object-fit: cover;">
|
|
458
462
|
```
|
|
459
463
|
|
|
460
|
-
#### Remote URL (
|
|
464
|
+
#### Remote URL Source (Download Before Saving)
|
|
461
465
|
```html
|
|
462
466
|
<img src="https://images.example.com/hero.png" alt="Hero image" style="width: 220pt; height: 140pt; object-fit: cover;">
|
|
463
467
|
```
|
|
464
468
|
|
|
469
|
+
If the image source starts on the web, download it into `<slides-dir>/assets/` and change the saved slide HTML to `./assets/<file>`.
|
|
470
|
+
|
|
465
471
|
#### Placeholder (Image Stand-In)
|
|
466
472
|
```html
|
|
467
473
|
<div data-image-placeholder style="width: 220pt; height: 140pt; border: 1px dashed #c7c7c7; background: #f3f4f6; display: flex; align-items: center; justify-content: center;">
|
|
@@ -474,7 +480,7 @@ Rules:
|
|
|
474
480
|
- Use `./assets/<file>` as the default image contract for slide HTML.
|
|
475
481
|
- Keep slide assets in `<slides-dir>/assets/`.
|
|
476
482
|
- `data:` URLs are allowed for fully self-contained slides.
|
|
477
|
-
-
|
|
483
|
+
- Do not leave remote `http(s)://` image URLs in saved slide HTML; download source images into `<slides-dir>/assets/` and reference them as `./assets/<file>`.
|
|
478
484
|
- Do not use absolute filesystem paths in slide HTML.
|
|
479
485
|
- Do not use non-body `background-image` for content imagery; use `<img>` instead.
|
|
480
486
|
- Use `data-image-placeholder` to reserve space when no image is available yet.
|
|
@@ -536,28 +542,30 @@ This skill is **Stage 2**. It works from the `slide-outline.md` approved by the
|
|
|
536
542
|
### Steps
|
|
537
543
|
|
|
538
544
|
1. **Analyze + Design**: Read `slide-outline.md`, decide theme/layout, generate HTML slides
|
|
539
|
-
2. **
|
|
545
|
+
2. **Diagram choice**: If a slide needs a complex diagram (architecture, workflows, relationship maps, multi-node concepts), prefer `tldraw`. Export the diagram with `slides-grab tldraw` and reference the generated local asset from the slide HTML.
|
|
546
|
+
3. **Validate slides**: After slide generation or edits, automatically run:
|
|
540
547
|
```bash
|
|
541
548
|
slides-grab validate --slides-dir <path>
|
|
542
549
|
```
|
|
543
|
-
|
|
544
|
-
|
|
550
|
+
4. **Auto-fix validation issues**: If validation fails, fix the source HTML/CSS and re-run validation until it passes
|
|
551
|
+
5. **Auto-build viewer**: After validation passes, automatically run:
|
|
545
552
|
```bash
|
|
546
553
|
node scripts/build-viewer.js --slides-dir <path>
|
|
547
554
|
```
|
|
548
|
-
|
|
555
|
+
6. **Guide user to review**: Tell the user to check slides in the browser:
|
|
549
556
|
```
|
|
550
557
|
open <slides-dir>/viewer.html
|
|
551
558
|
```
|
|
552
|
-
|
|
559
|
+
7. **Revision loop**: When the user requests changes to specific slides:
|
|
553
560
|
- Edit only the relevant HTML file
|
|
554
561
|
- Re-run `slides-grab validate --slides-dir <path>` and fix any failures
|
|
555
562
|
- Re-run `node scripts/build-viewer.js --slides-dir <path>` to rebuild the viewer
|
|
556
563
|
- Guide user to review again
|
|
557
|
-
|
|
564
|
+
8. **Completion**: Repeat the revision loop until the user signals approval for PPTX conversion
|
|
558
565
|
|
|
559
566
|
### Absolute Rules
|
|
560
567
|
- **Never start PPTX conversion without approval** — PPTX conversion is the responsibility of `pptx-skill` and requires explicit user approval.
|
|
568
|
+
- **Prefer tldraw for complex diagrams** — Use `slides-grab tldraw` when the slide needs a non-trivial diagram instead of forcing dense diagram geometry into HTML/CSS.
|
|
561
569
|
- **Never skip validation** — Run `slides-grab validate --slides-dir <path>` after generation or edits and fix failures before review.
|
|
562
570
|
- **Never forget to build the viewer** — Run `node scripts/build-viewer.js --slides-dir <path>` every time slides are generated or modified.
|
|
563
571
|
|
|
@@ -567,6 +575,6 @@ This skill is **Stage 2**. It works from the `slide-outline.md` approved by the
|
|
|
567
575
|
|
|
568
576
|
1. **CSS gradients**: Not supported in PowerPoint conversion — replace with background images
|
|
569
577
|
2. **Webfonts**: Always include the Pretendard CDN link
|
|
570
|
-
3. **Image paths**: Use `./assets/<file>` from each `slide-XX.html`; avoid absolute filesystem paths
|
|
578
|
+
3. **Image paths**: Use `./assets/<file>` from each `slide-XX.html`; avoid absolute filesystem paths and do not leave remote `http(s)://` image URLs in saved slide HTML
|
|
571
579
|
4. **Colors**: Always include `#` prefix in CSS
|
|
572
580
|
5. **Text rules**: Never place text directly in div/span
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
- Always include alt on img tags.
|
|
10
10
|
- Use `./assets/<file>` as the default image contract for slide HTML.
|
|
11
11
|
- Keep slide assets in `<slides-dir>/assets/`.
|
|
12
|
+
- Use `tldraw`-generated assets for complex diagrams whenever possible.
|
|
12
13
|
- `data:` URLs are allowed for fully self-contained slides.
|
|
13
|
-
-
|
|
14
|
+
- Do not leave remote `http(s)://` image URLs in saved slide HTML; download source images into `<slides-dir>/assets/` and reference them as `./assets/<file>`.
|
|
14
15
|
- Do not use absolute filesystem paths in slide HTML.
|
|
15
16
|
- Do not use non-body `background-image` for content imagery; use `<img>` instead.
|
|
16
17
|
- Use `data-image-placeholder` to reserve space when no image is available yet.
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
- After slide generation or edits, run `slides-grab validate --slides-dir <path>`.
|
|
24
25
|
- After validation passes, run `slides-grab build-viewer --slides-dir <path>`.
|
|
25
26
|
- Edit only the relevant HTML file during revision loops.
|
|
27
|
+
- Prefer `slides-grab tldraw` + local exported assets for architecture, workflow, relationship, and other complex diagrams.
|
|
26
28
|
- Never start PPTX conversion without explicit approval.
|
|
27
29
|
- Never forget to build the viewer after slide changes.
|
|
28
30
|
- Do not persist runtime-only editor/viewer injections in saved slide HTML.
|