slides-grab 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -8
- package/bin/ppt-agent.js +0 -12
- package/convert.cjs +7 -233
- package/package.json +2 -4
- package/skills/slides-grab/SKILL.md +8 -5
- package/skills/slides-grab/references/presentation-workflow-reference.md +52 -0
- package/skills/slides-grab-design/SKILL.md +5 -2
- package/skills/slides-grab-design/references/design-rules.md +49 -0
- package/skills/slides-grab-design/references/design-system-full.md +572 -0
- package/skills/slides-grab-design/references/detailed-design-rules.md +35 -0
- package/skills/slides-grab-export/SKILL.md +10 -5
- package/skills/slides-grab-export/references/export-rules.md +22 -0
- package/skills/slides-grab-export/references/html2pptx.md +625 -0
- package/skills/slides-grab-export/references/ooxml.md +427 -0
- package/skills/slides-grab-export/references/pptx-skill-reference.md +223 -0
- package/skills/slides-grab-plan/SKILL.md +5 -2
- package/skills/slides-grab-plan/references/outline-format.md +47 -0
- package/skills/slides-grab-plan/references/plan-workflow-reference.md +140 -0
- package/src/editor/codex-edit.js +2 -2
- package/src/pptx-raster-export.cjs +238 -0
- package/scripts/install-codex-skills.js +0 -119
package/README.md
CHANGED
|
@@ -31,16 +31,16 @@ Paste one of these into your coding agent:
|
|
|
31
31
|
**Claude Code:**
|
|
32
32
|
|
|
33
33
|
```
|
|
34
|
-
Read https://raw.githubusercontent.com/vkehfdl1/slides-grab/main/docs/
|
|
34
|
+
Read https://raw.githubusercontent.com/vkehfdl1/slides-grab/main/docs/installation/claude.md and follow every step.
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
**Codex:**
|
|
38
38
|
|
|
39
39
|
```
|
|
40
|
-
Read https://raw.githubusercontent.com/vkehfdl1/slides-grab/main/docs/
|
|
40
|
+
Read https://raw.githubusercontent.com/vkehfdl1/slides-grab/main/docs/installation/codex.md and follow every step.
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Or
|
|
43
|
+
Or use the repo directly if you want to develop on slides-grab itself:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
git clone https://github.com/vkehfdl1/slides-grab.git && cd slides-grab
|
|
@@ -49,6 +49,14 @@ npm ci && npx playwright install chromium
|
|
|
49
49
|
|
|
50
50
|
> Requires **Node.js >= 18**.
|
|
51
51
|
|
|
52
|
+
### No-clone install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install slides-grab
|
|
56
|
+
npx playwright install chromium
|
|
57
|
+
npx skills add ./node_modules/slides-grab -g -a codex -a claude-code --yes --copy
|
|
58
|
+
```
|
|
59
|
+
|
|
52
60
|
## Why This Project?
|
|
53
61
|
|
|
54
62
|
There are many AI tools that generate slide HTML. Almost none let you **visually point at what you want changed** and iterate in-place. slides-grab fills that gap:
|
|
@@ -118,19 +126,25 @@ This command reuses the HTML to PPTX pipeline and emits a `.pptx` deck intended
|
|
|
118
126
|
|
|
119
127
|
## Installation Guides
|
|
120
128
|
|
|
121
|
-
- [Claude Code setup](docs/prompts/setup-claude.md)
|
|
122
|
-
- [Codex setup](docs/prompts/setup-codex.md)
|
|
123
129
|
- [Claude detailed guide](docs/installation/claude.md)
|
|
124
130
|
- [Codex detailed guide](docs/installation/codex.md)
|
|
125
131
|
|
|
126
132
|
## npm Package
|
|
127
133
|
|
|
128
|
-
Also available as an npm package for standalone CLI usage:
|
|
134
|
+
Also available as an npm package for standalone CLI + skill usage:
|
|
129
135
|
|
|
130
136
|
```bash
|
|
131
137
|
npm install slides-grab
|
|
132
138
|
```
|
|
133
139
|
|
|
140
|
+
Install shared agent skills with Vercel Agent Skills:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npx skills add ./node_modules/slides-grab -g -a codex -a claude-code --yes --copy
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
This npm-install path is enough for normal usage. Clone the repo only when you want to modify or contribute to `slides-grab` itself.
|
|
147
|
+
|
|
134
148
|
## Project Structure
|
|
135
149
|
|
|
136
150
|
```
|
|
@@ -139,8 +153,7 @@ src/editor/ Visual editor (HTML + JS client modules)
|
|
|
139
153
|
scripts/ Build, validate, convert, editor server
|
|
140
154
|
templates/ Slide HTML templates (cover, content, chart, ...)
|
|
141
155
|
themes/ Color themes (modern-dark, executive, sage, ...)
|
|
142
|
-
|
|
143
|
-
skills/ Codex skill definitions
|
|
156
|
+
skills/ Shared Vercel-installable agent skills + references
|
|
144
157
|
docs/ Installation & usage guides
|
|
145
158
|
```
|
|
146
159
|
|
package/bin/ppt-agent.js
CHANGED
|
@@ -167,18 +167,6 @@ program
|
|
|
167
167
|
await runCommand('scripts/editor-server.js', args);
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
-
program
|
|
171
|
-
.command('install-codex-skills')
|
|
172
|
-
.description('Install project Codex skills into $CODEX_HOME/skills (default: ~/.codex/skills)')
|
|
173
|
-
.option('--force', 'Overwrite existing skill directories')
|
|
174
|
-
.option('--dry-run', 'Preview what would be installed')
|
|
175
|
-
.action(async (options = {}) => {
|
|
176
|
-
const args = [];
|
|
177
|
-
if (options.force) args.push('--force');
|
|
178
|
-
if (options.dryRun) args.push('--dry-run');
|
|
179
|
-
await runCommand('scripts/install-codex-skills.js', args);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
170
|
// --- Template/theme discovery commands ---
|
|
183
171
|
|
|
184
172
|
program
|
package/convert.cjs
CHANGED
|
@@ -1,239 +1,12 @@
|
|
|
1
|
-
const PptxGenJS = require('pptxgenjs');
|
|
2
|
-
const { chromium } = require('playwright');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const sharp = require('sharp');
|
|
6
1
|
const {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// Inline a simplified version that uses Playwright Chromium (not Chrome)
|
|
13
|
-
const DEFAULT_SLIDES_DIR = 'slides';
|
|
14
|
-
const DEFAULT_OUTPUT = 'output.pptx';
|
|
15
|
-
const DEFAULT_RESOLUTION = '2160p';
|
|
16
|
-
const DEFAULT_CAPTURE_VIEWPORT = { width: 960, height: 540 };
|
|
17
|
-
const DEFAULT_CAPTURE_DEVICE_SCALE_FACTOR = 2;
|
|
18
|
-
const TARGET_RASTER_DPI = 150;
|
|
19
|
-
const TARGET_SLIDE_SIZE_IN = { width: 13.33, height: 7.5 };
|
|
20
|
-
|
|
21
|
-
function normalizeDimension(value, fallback) {
|
|
22
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
23
|
-
return fallback;
|
|
24
|
-
}
|
|
25
|
-
return Math.max(1, Math.round(value));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function buildPageOptions(resolution = '') {
|
|
29
|
-
const targetResolution = getResolutionSize(resolution);
|
|
30
|
-
return {
|
|
31
|
-
viewport: {
|
|
32
|
-
width: DEFAULT_CAPTURE_VIEWPORT.width,
|
|
33
|
-
height: DEFAULT_CAPTURE_VIEWPORT.height,
|
|
34
|
-
},
|
|
35
|
-
deviceScaleFactor: targetResolution
|
|
36
|
-
? targetResolution.height / DEFAULT_CAPTURE_VIEWPORT.height
|
|
37
|
-
: DEFAULT_CAPTURE_DEVICE_SCALE_FACTOR,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getTargetRasterSize(resolution = '') {
|
|
42
|
-
const targetResolution = getResolutionSize(resolution);
|
|
43
|
-
if (targetResolution) {
|
|
44
|
-
return targetResolution;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
width: Math.round(TARGET_SLIDE_SIZE_IN.width * TARGET_RASTER_DPI),
|
|
49
|
-
height: Math.round(TARGET_SLIDE_SIZE_IN.height * TARGET_RASTER_DPI),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function printUsage() {
|
|
54
|
-
process.stdout.write(
|
|
55
|
-
[
|
|
56
|
-
'Usage: node convert.cjs [options]',
|
|
57
|
-
'',
|
|
58
|
-
'Options:',
|
|
59
|
-
` --slides-dir <path> Slide directory (default: ${DEFAULT_SLIDES_DIR})`,
|
|
60
|
-
` --output <path> Output pptx path (default: ${DEFAULT_OUTPUT})`,
|
|
61
|
-
` --resolution <preset> Raster size preset: ${getResolutionChoices().join('|')}|4k (default: ${DEFAULT_RESOLUTION})`,
|
|
62
|
-
' -h, --help Show this help message',
|
|
63
|
-
].join('\n'),
|
|
64
|
-
);
|
|
65
|
-
process.stdout.write('\n');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function readOptionValue(args, index, optionName) {
|
|
69
|
-
const next = args[index + 1];
|
|
70
|
-
if (!next || next.startsWith('-')) {
|
|
71
|
-
throw new Error(`Missing value for ${optionName}.`);
|
|
72
|
-
}
|
|
73
|
-
return next;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function parseArgs(args) {
|
|
77
|
-
const options = {
|
|
78
|
-
slidesDir: DEFAULT_SLIDES_DIR,
|
|
79
|
-
output: DEFAULT_OUTPUT,
|
|
80
|
-
resolution: DEFAULT_RESOLUTION,
|
|
81
|
-
help: false,
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
85
|
-
const arg = args[i];
|
|
86
|
-
if (arg === '-h' || arg === '--help') {
|
|
87
|
-
options.help = true;
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (arg === '--slides-dir') {
|
|
92
|
-
options.slidesDir = readOptionValue(args, i, '--slides-dir');
|
|
93
|
-
i += 1;
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (arg.startsWith('--slides-dir=')) {
|
|
98
|
-
options.slidesDir = arg.slice('--slides-dir='.length);
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (arg === '--output') {
|
|
103
|
-
options.output = readOptionValue(args, i, '--output');
|
|
104
|
-
i += 1;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (arg.startsWith('--output=')) {
|
|
109
|
-
options.output = arg.slice('--output='.length);
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (arg === '--resolution') {
|
|
114
|
-
options.resolution = normalizeResolutionPreset(readOptionValue(args, i, '--resolution'));
|
|
115
|
-
i += 1;
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (arg.startsWith('--resolution=')) {
|
|
120
|
-
options.resolution = normalizeResolutionPreset(arg.slice('--resolution='.length));
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
throw new Error(`Unknown option: ${arg}`);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (typeof options.slidesDir !== 'string' || options.slidesDir.trim() === '') {
|
|
128
|
-
throw new Error('--slides-dir must be a non-empty string.');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (typeof options.output !== 'string' || options.output.trim() === '') {
|
|
132
|
-
throw new Error('--output must be a non-empty string.');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
options.slidesDir = options.slidesDir.trim();
|
|
136
|
-
options.output = options.output.trim();
|
|
137
|
-
options.resolution = normalizeResolutionPreset(options.resolution);
|
|
138
|
-
return options;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async function convertSlide(htmlFile, pres, browser, options = {}) {
|
|
142
|
-
const filePath = path.isAbsolute(htmlFile) ? htmlFile : path.join(process.cwd(), htmlFile);
|
|
143
|
-
|
|
144
|
-
const page = await browser.newPage(buildPageOptions(options.resolution));
|
|
145
|
-
await page.goto(`file://${filePath}`);
|
|
146
|
-
|
|
147
|
-
const bodyDimensions = await page.evaluate(() => {
|
|
148
|
-
const body = document.body;
|
|
149
|
-
const style = window.getComputedStyle(body);
|
|
150
|
-
return {
|
|
151
|
-
width: parseFloat(style.width),
|
|
152
|
-
height: parseFloat(style.height),
|
|
153
|
-
};
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
await page.setViewportSize({
|
|
157
|
-
width: normalizeDimension(bodyDimensions.width, DEFAULT_CAPTURE_VIEWPORT.width),
|
|
158
|
-
height: normalizeDimension(bodyDimensions.height, DEFAULT_CAPTURE_VIEWPORT.height)
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// Take screenshot and add as full-slide image
|
|
162
|
-
const screenshot = await page.screenshot({ type: 'png' });
|
|
163
|
-
await page.close();
|
|
164
|
-
|
|
165
|
-
// Resize to exact slide dimensions (13.33" x 7.5" at 150 DPI)
|
|
166
|
-
const targetSize = getTargetRasterSize(options.resolution);
|
|
167
|
-
|
|
168
|
-
const resized = await sharp(screenshot)
|
|
169
|
-
.resize(targetSize.width, targetSize.height, { fit: 'fill' })
|
|
170
|
-
.png()
|
|
171
|
-
.toBuffer();
|
|
172
|
-
|
|
173
|
-
const tmpPath = path.join(process.env.TMPDIR || '/tmp', `slide-${Date.now()}-${Math.random().toString(36).slice(2)}.png`);
|
|
174
|
-
fs.writeFileSync(tmpPath, resized);
|
|
175
|
-
|
|
176
|
-
const slide = pres.addSlide();
|
|
177
|
-
slide.addImage({
|
|
178
|
-
path: tmpPath,
|
|
179
|
-
x: 0,
|
|
180
|
-
y: 0,
|
|
181
|
-
w: '100%',
|
|
182
|
-
h: '100%'
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
return tmpPath;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async function main() {
|
|
189
|
-
const options = parseArgs(process.argv.slice(2));
|
|
190
|
-
if (options.help) {
|
|
191
|
-
printUsage();
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const pres = new PptxGenJS();
|
|
196
|
-
pres.layout = 'LAYOUT_WIDE'; // 16:9
|
|
197
|
-
|
|
198
|
-
const slidesDir = path.resolve(process.cwd(), options.slidesDir);
|
|
199
|
-
const { ensureSlidesPassValidation } = await import('./scripts/validate-slides.js');
|
|
200
|
-
await ensureSlidesPassValidation(slidesDir, { exportLabel: 'PPTX export' });
|
|
201
|
-
const files = fs.readdirSync(slidesDir)
|
|
202
|
-
.filter(f => f.endsWith('.html'))
|
|
203
|
-
.sort();
|
|
204
|
-
|
|
205
|
-
console.log(`Converting ${files.length} slides...`);
|
|
206
|
-
|
|
207
|
-
// Launch Chromium (not Chrome)
|
|
208
|
-
const browser = await chromium.launch();
|
|
209
|
-
const tmpFiles = [];
|
|
210
|
-
|
|
211
|
-
for (const file of files) {
|
|
212
|
-
const filePath = path.join(slidesDir, file);
|
|
213
|
-
console.log(` Processing: ${file}`);
|
|
214
|
-
try {
|
|
215
|
-
const tmpPath = await convertSlide(filePath, pres, browser, { resolution: options.resolution });
|
|
216
|
-
tmpFiles.push(tmpPath);
|
|
217
|
-
console.log(` ✓ ${file} done`);
|
|
218
|
-
} catch (err) {
|
|
219
|
-
console.error(` ✗ ${file} error: ${err.message}`);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
await browser.close();
|
|
224
|
-
|
|
225
|
-
const outputFile = path.resolve(process.cwd(), options.output);
|
|
226
|
-
await pres.writeFile({ fileName: outputFile });
|
|
227
|
-
console.log(`\nSaved: ${outputFile}`);
|
|
228
|
-
|
|
229
|
-
// Cleanup tmp files
|
|
230
|
-
for (const f of tmpFiles) {
|
|
231
|
-
try { fs.unlinkSync(f); } catch {}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
2
|
+
buildPageOptions,
|
|
3
|
+
getTargetRasterSize,
|
|
4
|
+
main,
|
|
5
|
+
parseArgs,
|
|
6
|
+
} = require('./src/pptx-raster-export.cjs');
|
|
234
7
|
|
|
235
8
|
if (require.main === module) {
|
|
236
|
-
main().catch(err => {
|
|
9
|
+
main().catch((err) => {
|
|
237
10
|
console.error('Fatal error:', err);
|
|
238
11
|
process.exit(1);
|
|
239
12
|
});
|
|
@@ -242,5 +15,6 @@ if (require.main === module) {
|
|
|
242
15
|
module.exports = {
|
|
243
16
|
buildPageOptions,
|
|
244
17
|
getTargetRasterSize,
|
|
18
|
+
main,
|
|
245
19
|
parseArgs,
|
|
246
20
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slides-grab",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
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,7 +38,6 @@
|
|
|
38
38
|
"scripts/figma-export.js",
|
|
39
39
|
"scripts/html2pdf.js",
|
|
40
40
|
"scripts/html2pptx.js",
|
|
41
|
-
"scripts/install-codex-skills.js",
|
|
42
41
|
"scripts/validate-slides.js",
|
|
43
42
|
"skills/",
|
|
44
43
|
"src/",
|
|
@@ -52,8 +51,7 @@
|
|
|
52
51
|
"build-viewer": "node scripts/build-viewer.js",
|
|
53
52
|
"validate": "node scripts/validate-slides.js",
|
|
54
53
|
"convert": "node convert.cjs",
|
|
55
|
-
"
|
|
56
|
-
"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",
|
|
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",
|
|
57
55
|
"test:e2e": "node --test tests/editor/editor-ui.e2e.test.js tests/editor/editor-concurrency.e2e.test.js"
|
|
58
56
|
},
|
|
59
57
|
"dependencies": {
|
|
@@ -15,7 +15,7 @@ Guides you through the complete presentation pipeline from topic to exported fil
|
|
|
15
15
|
|
|
16
16
|
### Stage 1 — Plan
|
|
17
17
|
|
|
18
|
-
Use **slides-grab-plan**
|
|
18
|
+
Use the installed **slides-grab-plan** skill.
|
|
19
19
|
|
|
20
20
|
1. Take user's topic, audience, and tone.
|
|
21
21
|
2. Create `slide-outline.md`.
|
|
@@ -26,13 +26,13 @@ Use **slides-grab-plan** (`skills/slides-grab-plan/SKILL.md`).
|
|
|
26
26
|
|
|
27
27
|
### Stage 2 — Design
|
|
28
28
|
|
|
29
|
-
Use **slides-grab-design**
|
|
29
|
+
Use the installed **slides-grab-design** skill.
|
|
30
30
|
|
|
31
31
|
1. Read approved `slide-outline.md`.
|
|
32
32
|
2. Generate `slide-*.html` files in the slides workspace (default: `slides/`).
|
|
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
|
-
5. Build the viewer: `
|
|
35
|
+
5. Build the viewer: `slides-grab build-viewer --slides-dir <path>`
|
|
36
36
|
6. Present viewer to user for review.
|
|
37
37
|
7. Revise individual slides based on feedback, then re-run validation and rebuild the viewer.
|
|
38
38
|
8. Optionally launch the visual editor: `slides-grab edit --slides-dir <path>`
|
|
@@ -41,7 +41,7 @@ Use **slides-grab-design** (`skills/slides-grab-design/SKILL.md`).
|
|
|
41
41
|
|
|
42
42
|
### Stage 3 — Export
|
|
43
43
|
|
|
44
|
-
Use **slides-grab-export**
|
|
44
|
+
Use the installed **slides-grab-export** skill.
|
|
45
45
|
|
|
46
46
|
1. Confirm user wants conversion.
|
|
47
47
|
2. Export to PPTX: `slides-grab convert --slides-dir <path> --output <name>.pptx` (**experimental / unstable**)
|
|
@@ -57,4 +57,7 @@ Use **slides-grab-export** (`skills/slides-grab-export/SKILL.md`).
|
|
|
57
57
|
3. **Read each stage's SKILL.md** for detailed rules — this skill only orchestrates.
|
|
58
58
|
4. **Use `decks/<deck-name>/`** as the slides workspace for multi-deck projects.
|
|
59
59
|
5. **Call out export risk clearly**: PPTX and Figma export are experimental / unstable and must be described as best-effort output.
|
|
60
|
-
6.
|
|
60
|
+
6. Use the stage skills as the source of truth for plan, design, and export rules.
|
|
61
|
+
|
|
62
|
+
## Reference
|
|
63
|
+
- `references/presentation-workflow-reference.md` — archived end-to-end workflow guidance from the legacy skill set
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Presentation Skill - Full Workflow Orchestrator
|
|
2
|
+
|
|
3
|
+
Guides you through the complete presentation pipeline from topic to exported file.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Workflow
|
|
8
|
+
|
|
9
|
+
### Stage 1 — Plan
|
|
10
|
+
|
|
11
|
+
Use **plan-skill** (`.claude/skills/plan-skill/SKILL.md`).
|
|
12
|
+
|
|
13
|
+
1. Take user's topic, audience, and tone.
|
|
14
|
+
2. Delegate outline creation to `organizer-agent`.
|
|
15
|
+
3. Present `slide-outline.md` to user.
|
|
16
|
+
4. Revise until user explicitly approves.
|
|
17
|
+
|
|
18
|
+
**Do not proceed to Stage 2 without approval.**
|
|
19
|
+
|
|
20
|
+
### Stage 2 — Design
|
|
21
|
+
|
|
22
|
+
Use **design-skill** (`.claude/skills/design-skill/SKILL.md`).
|
|
23
|
+
|
|
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: `node scripts/build-viewer.js --slides-dir <path>`
|
|
29
|
+
6. Present viewer to user for review.
|
|
30
|
+
7. Revise individual slides based on feedback, then re-run validation and rebuild the viewer.
|
|
31
|
+
8. Optionally launch the visual editor: `slides-grab edit --slides-dir <path>`
|
|
32
|
+
|
|
33
|
+
**Do not proceed to Stage 3 without approval.**
|
|
34
|
+
|
|
35
|
+
### Stage 3 — Export
|
|
36
|
+
|
|
37
|
+
Use **pptx-skill** (`.claude/skills/pptx-skill/SKILL.md`).
|
|
38
|
+
|
|
39
|
+
1. Confirm user wants conversion.
|
|
40
|
+
2. Export to PPTX: `slides-grab convert --slides-dir <path> --output <name>.pptx` (**experimental / unstable**)
|
|
41
|
+
3. Export to PDF (if requested): `slides-grab pdf --slides-dir <path> --output <name>.pdf`
|
|
42
|
+
4. Report results.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Rules
|
|
47
|
+
|
|
48
|
+
1. **Always follow the stage order**: Plan → Design → Export.
|
|
49
|
+
2. **Get explicit user approval** before advancing to the next stage.
|
|
50
|
+
3. **Read each stage's SKILL.md** for detailed rules — this skill only orchestrates.
|
|
51
|
+
4. **Use `decks/<deck-name>/`** as the slides workspace for multi-deck projects.
|
|
52
|
+
5. **Call out export risk clearly**: PPTX and Figma export are experimental / unstable and should be described as best-effort output.
|
|
@@ -26,7 +26,7 @@ Generate high-quality `slide-XX.html` files in the selected slides workspace (`s
|
|
|
26
26
|
2. Generate slide HTML files with 2-digit numbering in selected `--slides-dir`.
|
|
27
27
|
3. Run `slides-grab validate --slides-dir <path>` after generation or edits.
|
|
28
28
|
4. If validation fails, automatically fix the source slide HTML/CSS and re-run validation until it passes.
|
|
29
|
-
5. Run `
|
|
29
|
+
5. Run `slides-grab build-viewer --slides-dir <path>` only after validation passes.
|
|
30
30
|
6. Iterate on user feedback by editing only requested slide files, then re-run validation and rebuild the viewer.
|
|
31
31
|
7. Keep revising until user approves conversion stage.
|
|
32
32
|
|
|
@@ -39,7 +39,10 @@ Generate high-quality `slide-XX.html` files in the selected slides workspace (`s
|
|
|
39
39
|
- Prefer `<img>` for slide imagery and `data-image-placeholder` when no final asset exists.
|
|
40
40
|
- Do not present slides for review until `slides-grab validate --slides-dir <path>` passes.
|
|
41
41
|
- Do not start conversion before approval.
|
|
42
|
+
- Use the packaged CLI and bundled references only; do not depend on unpublished agent-specific files.
|
|
42
43
|
|
|
43
44
|
## Reference
|
|
44
45
|
For full constraints and style system, follow:
|
|
45
|
-
-
|
|
46
|
+
- `references/design-rules.md`
|
|
47
|
+
- `references/detailed-design-rules.md`
|
|
48
|
+
- `references/design-system-full.md` — archived full design system, templates, and advanced pattern guidance
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# slides-grab Design Reference
|
|
2
|
+
|
|
3
|
+
These are the packaged design rules for installable `slides-grab` skills.
|
|
4
|
+
|
|
5
|
+
## Package-first commands
|
|
6
|
+
- Validate slides: `slides-grab validate --slides-dir <path>`
|
|
7
|
+
- Build review viewer: `slides-grab build-viewer --slides-dir <path>`
|
|
8
|
+
- Launch editor: `slides-grab edit --slides-dir <path>`
|
|
9
|
+
|
|
10
|
+
## Slide spec
|
|
11
|
+
- Slide size: `720pt x 405pt` (16:9)
|
|
12
|
+
- Font: Pretendard
|
|
13
|
+
- Semantic text tags only: `p`, `h1-h6`, `ul`, `ol`, `li`
|
|
14
|
+
- CSS colors must include `#`
|
|
15
|
+
- Avoid CSS gradients for PPTX-targeted decks
|
|
16
|
+
|
|
17
|
+
## Asset rules
|
|
18
|
+
- Store deck-local assets in `<slides-dir>/assets/`
|
|
19
|
+
- Reference deck-local assets as `./assets/<file>`
|
|
20
|
+
- Allow `data:` URLs only when the slide must be fully self-contained
|
|
21
|
+
- Never use absolute filesystem paths
|
|
22
|
+
|
|
23
|
+
## Package-published theme references
|
|
24
|
+
- `themes/executive.css`
|
|
25
|
+
- `themes/sage.css`
|
|
26
|
+
- `themes/modern-dark.css`
|
|
27
|
+
- `themes/corporate.css`
|
|
28
|
+
- `themes/warm.css`
|
|
29
|
+
|
|
30
|
+
## Package-published template references
|
|
31
|
+
- `templates/cover.html`
|
|
32
|
+
- `templates/contents.html`
|
|
33
|
+
- `templates/section-divider.html`
|
|
34
|
+
- `templates/content.html`
|
|
35
|
+
- `templates/statistics.html`
|
|
36
|
+
- `templates/split-layout.html`
|
|
37
|
+
- `templates/team.html`
|
|
38
|
+
- `templates/quote.html`
|
|
39
|
+
- `templates/timeline.html`
|
|
40
|
+
- `templates/closing.html`
|
|
41
|
+
- `templates/chart.html`
|
|
42
|
+
- `templates/diagram.html`
|
|
43
|
+
- `templates/custom/`
|
|
44
|
+
|
|
45
|
+
## Review loop
|
|
46
|
+
- Generate or edit only the needed slide files.
|
|
47
|
+
- Re-run validation after every generation/edit pass.
|
|
48
|
+
- Rebuild the viewer only after validation passes.
|
|
49
|
+
- Do not move to export until the user approves the reviewed deck.
|