slides-grab 1.0.0 → 1.1.3
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 +39 -5
- package/bin/ppt-agent.js +54 -2
- package/convert.cjs +77 -15
- package/package.json +21 -4
- package/scripts/build-viewer.js +349 -0
- package/scripts/editor-server.js +7 -1
- package/scripts/figma-export.js +148 -0
- package/scripts/html2pdf.js +476 -32
- package/scripts/html2pptx.js +135 -0
- package/scripts/install-codex-skills.js +119 -0
- package/scripts/validate-slides.js +159 -371
- package/skills/{ppt-presentation-skill → slides-grab}/SKILL.md +16 -13
- package/skills/{ppt-design-skill → slides-grab-design}/SKILL.md +12 -5
- package/skills/{ppt-pptx-skill → slides-grab-export}/SKILL.md +7 -6
- package/skills/{ppt-plan-skill → slides-grab-plan}/SKILL.md +2 -2
- package/src/editor/codex-edit.js +136 -1
- package/src/editor/js/editor-init.js +10 -3
- package/src/export-resolution.cjs +58 -0
- package/src/figma.js +63 -0
- package/src/html2pptx.cjs +1166 -0
- package/src/image-contract.js +222 -0
- package/src/validation/cli.js +97 -0
- package/src/validation/core.js +688 -0
- package/templates/split-layout.html +3 -1
- package/AGENTS.md +0 -80
- package/PROGRESS.md +0 -39
- package/SETUP.md +0 -51
- package/prd.json +0 -135
- package/prd.md +0 -104
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Simple things like text, size, or bold can still be edited manually, just like i
|
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
11
|
The whole slides are HTML & CSS, the programming langauge (which is not) that outperformed by AI agents.<br>
|
|
12
|
-
So the slides are beautiful, easily editable by AI agents, and can be converted to
|
|
12
|
+
So the slides are beautiful, easily editable by AI agents, and can be converted to PDF or to experimental / unstable PPTX formats.
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
@@ -56,31 +56,66 @@ There are many AI tools that generate slide HTML. Almost none let you **visually
|
|
|
56
56
|
- **Plan** — Agent creates a structured slide outline from your topic/files
|
|
57
57
|
- **Design** — Agent generates each slide as a self-contained HTML file
|
|
58
58
|
- **Edit** — Browser-based editor with bbox selection, direct text editing, and agent-powered rewrites
|
|
59
|
-
- **Export** — One command to PPTX or
|
|
59
|
+
- **Export** — One command to PDF, plus experimental / unstable PPTX or Figma-export flows
|
|
60
60
|
|
|
61
61
|
## CLI Commands
|
|
62
62
|
|
|
63
63
|
All commands support `--slides-dir <path>` (default: `slides`).
|
|
64
64
|
|
|
65
|
+
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`.
|
|
66
|
+
|
|
65
67
|
```bash
|
|
66
68
|
slides-grab edit # Launch visual slide editor
|
|
67
69
|
slides-grab build-viewer # Build single-file viewer.html
|
|
68
70
|
slides-grab validate # Validate slide HTML (Playwright-based)
|
|
69
|
-
slides-grab convert # Export to PPTX
|
|
70
|
-
slides-grab
|
|
71
|
+
slides-grab convert # Export to experimental / unstable PPTX
|
|
72
|
+
slides-grab convert --resolution 2160p # Higher-resolution raster PPTX export
|
|
73
|
+
slides-grab figma # Export an experimental / unstable Figma Slides importable PPTX
|
|
74
|
+
slides-grab pdf # Export PDF in capture mode (default)
|
|
75
|
+
slides-grab pdf --resolution 2160p # Higher-resolution image-backed PDF export
|
|
76
|
+
slides-grab pdf --mode print # Export searchable/selectable text PDF
|
|
71
77
|
slides-grab list-templates # Show available slide templates
|
|
72
78
|
slides-grab list-themes # Show available color themes
|
|
73
79
|
```
|
|
74
80
|
|
|
81
|
+
## Image Contract
|
|
82
|
+
|
|
83
|
+
Slides should store local image files in `<slides-dir>/assets/` and reference them as `./assets/<file>` from each `slide-XX.html`.
|
|
84
|
+
|
|
85
|
+
- Preferred: `<img src="./assets/example.png" alt="...">`
|
|
86
|
+
- Allowed: `data:` URLs for fully self-contained slides
|
|
87
|
+
- Allowed with warnings: remote `https://` images
|
|
88
|
+
- Unsupported: absolute filesystem paths such as `/Users/...` or `C:\\...`
|
|
89
|
+
|
|
90
|
+
Run `slides-grab validate --slides-dir <path>` before export to catch missing local assets and discouraged path forms.
|
|
91
|
+
|
|
92
|
+
`slides-grab pdf` now defaults to `--mode capture`, which rasterizes each rendered slide into the PDF for better visual fidelity. Use `--mode print` when searchable/selectable browser text matters more than pixel-perfect parity.
|
|
93
|
+
|
|
94
|
+
`slides-grab pdf` and `slides-grab convert` now default to `2160p` / `4k` raster output for sharper exports. You can still override with `--resolution <preset>` using `720p`, `1080p`, `1440p`, `2160p`, or `4k` when you want smaller or faster artifacts.
|
|
95
|
+
|
|
75
96
|
### Multi-Deck Workflow
|
|
76
97
|
|
|
98
|
+
Prerequisite: create or generate a deck in `decks/my-deck/` first.
|
|
99
|
+
|
|
77
100
|
```bash
|
|
78
101
|
slides-grab edit --slides-dir decks/my-deck
|
|
79
102
|
slides-grab validate --slides-dir decks/my-deck
|
|
80
103
|
slides-grab pdf --slides-dir decks/my-deck --output decks/my-deck.pdf
|
|
104
|
+
slides-grab pdf --slides-dir decks/my-deck --mode print --output decks/my-deck-searchable.pdf
|
|
81
105
|
slides-grab convert --slides-dir decks/my-deck --output decks/my-deck.pptx
|
|
106
|
+
slides-grab figma --slides-dir decks/my-deck --output decks/my-deck-figma.pptx
|
|
82
107
|
```
|
|
83
108
|
|
|
109
|
+
> **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.
|
|
110
|
+
|
|
111
|
+
### Figma Workflow
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
slides-grab figma --slides-dir decks/my-deck --output decks/my-deck-figma.pptx
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This command reuses the HTML to PPTX pipeline and emits a `.pptx` deck intended for manual import into Figma Slides via `Import`. It does not upload to Figma directly. The Figma export path is **experimental / unstable** and should be treated as best-effort only.
|
|
118
|
+
|
|
84
119
|
## Installation Guides
|
|
85
120
|
|
|
86
121
|
- [Claude Code setup](docs/prompts/setup-claude.md)
|
|
@@ -117,4 +152,3 @@ docs/ Installation & usage guides
|
|
|
117
152
|
## Acknowledgment
|
|
118
153
|
|
|
119
154
|
This project is built based on the [ppt_team_agent](https://github.com/uxjoseph/ppt_team_agent) by Builder Josh. Huge thanks to him!
|
|
120
|
-
|
package/bin/ppt-agent.js
CHANGED
|
@@ -5,10 +5,25 @@ import { readFileSync } from 'node:fs';
|
|
|
5
5
|
import { dirname, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { Command } from 'commander';
|
|
8
|
+
import {
|
|
9
|
+
getFigmaImportCaveats,
|
|
10
|
+
getFigmaManualImportInstructions,
|
|
11
|
+
} from '../src/figma.js';
|
|
8
12
|
|
|
9
13
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
14
|
const packageRoot = resolve(__dirname, '..');
|
|
11
15
|
const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf-8'));
|
|
16
|
+
const figmaHelpText = [
|
|
17
|
+
'',
|
|
18
|
+
'Creates an experimental / unstable PowerPoint file tuned for Figma Slides manual import.',
|
|
19
|
+
'Treat both PPTX and Figma export as best-effort only.',
|
|
20
|
+
'',
|
|
21
|
+
'Manual import:',
|
|
22
|
+
` ${getFigmaManualImportInstructions()}`,
|
|
23
|
+
'',
|
|
24
|
+
'Figma import caveats:',
|
|
25
|
+
...getFigmaImportCaveats().map((caveat) => ` - ${caveat}`),
|
|
26
|
+
].join('\n');
|
|
12
27
|
|
|
13
28
|
/**
|
|
14
29
|
* Run a Node.js script from the package, with CWD set to the user's directory.
|
|
@@ -49,6 +64,10 @@ async function runCommand(relativePath, args = []) {
|
|
|
49
64
|
}
|
|
50
65
|
}
|
|
51
66
|
|
|
67
|
+
function collectRepeatedOption(value, previous = []) {
|
|
68
|
+
return [...previous, value];
|
|
69
|
+
}
|
|
70
|
+
|
|
52
71
|
const program = new Command();
|
|
53
72
|
|
|
54
73
|
program
|
|
@@ -69,23 +88,33 @@ program
|
|
|
69
88
|
|
|
70
89
|
program
|
|
71
90
|
.command('validate')
|
|
91
|
+
.alias('lint')
|
|
72
92
|
.description('Run structured validation on slide HTML files (Playwright-based)')
|
|
73
93
|
.option('--slides-dir <path>', 'Slide directory', 'slides')
|
|
94
|
+
.option('--format <format>', 'Output format: concise, json, json-full', 'concise')
|
|
95
|
+
.option('--slide <file>', 'Validate only the named slide file (repeatable)', collectRepeatedOption, [])
|
|
74
96
|
.action(async (options = {}) => {
|
|
75
|
-
const args = ['--slides-dir', options.slidesDir];
|
|
97
|
+
const args = ['--slides-dir', options.slidesDir, '--format', options.format];
|
|
98
|
+
for (const slide of options.slide || []) {
|
|
99
|
+
args.push('--slide', String(slide));
|
|
100
|
+
}
|
|
76
101
|
await runCommand('scripts/validate-slides.js', args);
|
|
77
102
|
});
|
|
78
103
|
|
|
79
104
|
program
|
|
80
105
|
.command('convert')
|
|
81
|
-
.description('Convert slide HTML files to PPTX')
|
|
106
|
+
.description('Convert slide HTML files to experimental / unstable PPTX')
|
|
82
107
|
.option('--slides-dir <path>', 'Slide directory', 'slides')
|
|
83
108
|
.option('--output <path>', 'Output PPTX file')
|
|
109
|
+
.option('--resolution <preset>', 'Raster size preset: 720p, 1080p, 1440p, 2160p, or 4k (default: 2160p)')
|
|
84
110
|
.action(async (options = {}) => {
|
|
85
111
|
const args = ['--slides-dir', options.slidesDir];
|
|
86
112
|
if (options.output) {
|
|
87
113
|
args.push('--output', String(options.output));
|
|
88
114
|
}
|
|
115
|
+
if (options.resolution) {
|
|
116
|
+
args.push('--resolution', String(options.resolution));
|
|
117
|
+
}
|
|
89
118
|
await runCommand('convert.cjs', args);
|
|
90
119
|
});
|
|
91
120
|
|
|
@@ -94,14 +123,37 @@ program
|
|
|
94
123
|
.description('Convert slide HTML files to PDF')
|
|
95
124
|
.option('--slides-dir <path>', 'Slide directory', 'slides')
|
|
96
125
|
.option('--output <path>', 'Output PDF file')
|
|
126
|
+
.option('--mode <mode>', 'PDF export mode: capture for visual fidelity, print for searchable text', 'capture')
|
|
127
|
+
.option('--resolution <preset>', 'Capture raster size preset: 720p, 1080p, 1440p, 2160p, or 4k (default: 2160p in capture mode)')
|
|
97
128
|
.action(async (options = {}) => {
|
|
98
129
|
const args = ['--slides-dir', options.slidesDir];
|
|
99
130
|
if (options.output) {
|
|
100
131
|
args.push('--output', String(options.output));
|
|
101
132
|
}
|
|
133
|
+
if (options.mode) {
|
|
134
|
+
args.push('--mode', String(options.mode));
|
|
135
|
+
}
|
|
136
|
+
if (options.resolution) {
|
|
137
|
+
args.push('--resolution', String(options.resolution));
|
|
138
|
+
}
|
|
102
139
|
await runCommand('scripts/html2pdf.js', args);
|
|
103
140
|
});
|
|
104
141
|
|
|
142
|
+
program
|
|
143
|
+
.command('figma')
|
|
144
|
+
.description('Export an experimental / unstable Figma Slides importable PPTX')
|
|
145
|
+
.helpOption('-h, --help', 'Show this help message')
|
|
146
|
+
.option('--slides-dir <path>', 'Slide directory', 'slides')
|
|
147
|
+
.option('--output <path>', 'Output PPTX file (default: <slides-dir>-figma.pptx)')
|
|
148
|
+
.addHelpText('after', figmaHelpText)
|
|
149
|
+
.action(async (options = {}) => {
|
|
150
|
+
const args = ['--slides-dir', options.slidesDir];
|
|
151
|
+
if (options.output) {
|
|
152
|
+
args.push('--output', String(options.output));
|
|
153
|
+
}
|
|
154
|
+
await runCommand('scripts/figma-export.js', args);
|
|
155
|
+
});
|
|
156
|
+
|
|
105
157
|
program
|
|
106
158
|
.command('edit')
|
|
107
159
|
.description('Start interactive slide editor with Codex image-based edit flow')
|
package/convert.cjs
CHANGED
|
@@ -3,13 +3,52 @@ const { chromium } = require('playwright');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const sharp = require('sharp');
|
|
6
|
+
const {
|
|
7
|
+
getResolutionChoices,
|
|
8
|
+
getResolutionSize,
|
|
9
|
+
normalizeResolutionPreset,
|
|
10
|
+
} = require('./src/export-resolution.cjs');
|
|
6
11
|
|
|
7
12
|
// Inline a simplified version that uses Playwright Chromium (not Chrome)
|
|
8
|
-
const PT_PER_PX = 0.75;
|
|
9
|
-
const PX_PER_IN = 96;
|
|
10
|
-
const EMU_PER_IN = 914400;
|
|
11
13
|
const DEFAULT_SLIDES_DIR = 'slides';
|
|
12
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
|
+
}
|
|
13
52
|
|
|
14
53
|
function printUsage() {
|
|
15
54
|
process.stdout.write(
|
|
@@ -19,6 +58,7 @@ function printUsage() {
|
|
|
19
58
|
'Options:',
|
|
20
59
|
` --slides-dir <path> Slide directory (default: ${DEFAULT_SLIDES_DIR})`,
|
|
21
60
|
` --output <path> Output pptx path (default: ${DEFAULT_OUTPUT})`,
|
|
61
|
+
` --resolution <preset> Raster size preset: ${getResolutionChoices().join('|')}|4k (default: ${DEFAULT_RESOLUTION})`,
|
|
22
62
|
' -h, --help Show this help message',
|
|
23
63
|
].join('\n'),
|
|
24
64
|
);
|
|
@@ -37,6 +77,7 @@ function parseArgs(args) {
|
|
|
37
77
|
const options = {
|
|
38
78
|
slidesDir: DEFAULT_SLIDES_DIR,
|
|
39
79
|
output: DEFAULT_OUTPUT,
|
|
80
|
+
resolution: DEFAULT_RESOLUTION,
|
|
40
81
|
help: false,
|
|
41
82
|
};
|
|
42
83
|
|
|
@@ -69,6 +110,17 @@ function parseArgs(args) {
|
|
|
69
110
|
continue;
|
|
70
111
|
}
|
|
71
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
|
+
|
|
72
124
|
throw new Error(`Unknown option: ${arg}`);
|
|
73
125
|
}
|
|
74
126
|
|
|
@@ -82,13 +134,14 @@ function parseArgs(args) {
|
|
|
82
134
|
|
|
83
135
|
options.slidesDir = options.slidesDir.trim();
|
|
84
136
|
options.output = options.output.trim();
|
|
137
|
+
options.resolution = normalizeResolutionPreset(options.resolution);
|
|
85
138
|
return options;
|
|
86
139
|
}
|
|
87
140
|
|
|
88
|
-
async function convertSlide(htmlFile, pres, browser) {
|
|
141
|
+
async function convertSlide(htmlFile, pres, browser, options = {}) {
|
|
89
142
|
const filePath = path.isAbsolute(htmlFile) ? htmlFile : path.join(process.cwd(), htmlFile);
|
|
90
143
|
|
|
91
|
-
const page = await browser.newPage();
|
|
144
|
+
const page = await browser.newPage(buildPageOptions(options.resolution));
|
|
92
145
|
await page.goto(`file://${filePath}`);
|
|
93
146
|
|
|
94
147
|
const bodyDimensions = await page.evaluate(() => {
|
|
@@ -101,8 +154,8 @@ async function convertSlide(htmlFile, pres, browser) {
|
|
|
101
154
|
});
|
|
102
155
|
|
|
103
156
|
await page.setViewportSize({
|
|
104
|
-
width:
|
|
105
|
-
height:
|
|
157
|
+
width: normalizeDimension(bodyDimensions.width, DEFAULT_CAPTURE_VIEWPORT.width),
|
|
158
|
+
height: normalizeDimension(bodyDimensions.height, DEFAULT_CAPTURE_VIEWPORT.height)
|
|
106
159
|
});
|
|
107
160
|
|
|
108
161
|
// Take screenshot and add as full-slide image
|
|
@@ -110,11 +163,10 @@ async function convertSlide(htmlFile, pres, browser) {
|
|
|
110
163
|
await page.close();
|
|
111
164
|
|
|
112
165
|
// Resize to exact slide dimensions (13.33" x 7.5" at 150 DPI)
|
|
113
|
-
const
|
|
114
|
-
const targetHeight = Math.round(7.5 * 150);
|
|
166
|
+
const targetSize = getTargetRasterSize(options.resolution);
|
|
115
167
|
|
|
116
168
|
const resized = await sharp(screenshot)
|
|
117
|
-
.resize(
|
|
169
|
+
.resize(targetSize.width, targetSize.height, { fit: 'fill' })
|
|
118
170
|
.png()
|
|
119
171
|
.toBuffer();
|
|
120
172
|
|
|
@@ -144,6 +196,8 @@ async function main() {
|
|
|
144
196
|
pres.layout = 'LAYOUT_WIDE'; // 16:9
|
|
145
197
|
|
|
146
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' });
|
|
147
201
|
const files = fs.readdirSync(slidesDir)
|
|
148
202
|
.filter(f => f.endsWith('.html'))
|
|
149
203
|
.sort();
|
|
@@ -158,7 +212,7 @@ async function main() {
|
|
|
158
212
|
const filePath = path.join(slidesDir, file);
|
|
159
213
|
console.log(` Processing: ${file}`);
|
|
160
214
|
try {
|
|
161
|
-
const tmpPath = await convertSlide(filePath, pres, browser);
|
|
215
|
+
const tmpPath = await convertSlide(filePath, pres, browser, { resolution: options.resolution });
|
|
162
216
|
tmpFiles.push(tmpPath);
|
|
163
217
|
console.log(` ✓ ${file} done`);
|
|
164
218
|
} catch (err) {
|
|
@@ -178,7 +232,15 @@ async function main() {
|
|
|
178
232
|
}
|
|
179
233
|
}
|
|
180
234
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
235
|
+
if (require.main === module) {
|
|
236
|
+
main().catch(err => {
|
|
237
|
+
console.error('Fatal error:', err);
|
|
238
|
+
process.exit(1);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
module.exports = {
|
|
243
|
+
buildPageOptions,
|
|
244
|
+
getTargetRasterSize,
|
|
245
|
+
parseArgs,
|
|
246
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slides-grab",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Agent-first presentation framework — plan, design, and visually edit HTML slides with Claude Code or Codex, then export to PPTX/
|
|
3
|
+
"version": "1.1.3",
|
|
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",
|
|
7
7
|
"repository": {
|
|
@@ -30,13 +30,30 @@
|
|
|
30
30
|
"bin": {
|
|
31
31
|
"slides-grab": "./bin/ppt-agent.js"
|
|
32
32
|
},
|
|
33
|
+
"files": [
|
|
34
|
+
"bin/",
|
|
35
|
+
"convert.cjs",
|
|
36
|
+
"scripts/build-viewer.js",
|
|
37
|
+
"scripts/editor-server.js",
|
|
38
|
+
"scripts/figma-export.js",
|
|
39
|
+
"scripts/html2pdf.js",
|
|
40
|
+
"scripts/html2pptx.js",
|
|
41
|
+
"scripts/install-codex-skills.js",
|
|
42
|
+
"scripts/validate-slides.js",
|
|
43
|
+
"skills/",
|
|
44
|
+
"src/",
|
|
45
|
+
"templates/",
|
|
46
|
+
"themes/",
|
|
47
|
+
"LICENSE",
|
|
48
|
+
"README.md"
|
|
49
|
+
],
|
|
33
50
|
"scripts": {
|
|
34
|
-
"html2pptx": "node
|
|
51
|
+
"html2pptx": "node scripts/html2pptx.js",
|
|
35
52
|
"build-viewer": "node scripts/build-viewer.js",
|
|
36
53
|
"validate": "node scripts/validate-slides.js",
|
|
37
54
|
"convert": "node convert.cjs",
|
|
38
55
|
"codex:install-skills": "node scripts/install-codex-skills.js --force",
|
|
39
|
-
"test": "node --test tests/editor/editor-codex-edit.test.js tests/pdf/html2pdf.test.js",
|
|
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",
|
|
40
57
|
"test:e2e": "node --test tests/editor/editor-ui.e2e.test.js tests/editor/editor-concurrency.e2e.test.js"
|
|
41
58
|
},
|
|
42
59
|
"dependencies": {
|