lazyslides 0.3.1 → 0.4.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/index.js CHANGED
@@ -112,6 +112,14 @@ export default function lazyslides(eleventyConfig, options = {}) {
112
112
  d2Cache.set(source, `<div class="d2-error">${safeMsg}</div>`);
113
113
  }
114
114
  }
115
+
116
+ // Terminate the D2 worker thread so the Node process can exit cleanly.
117
+ // The D2 class spawns a Worker for WASM but never exposes a cleanup method.
118
+ if (d2Instance?.worker) {
119
+ await d2Instance.worker.terminate();
120
+ d2Instance = null;
121
+ d2Available = null;
122
+ }
115
123
  });
116
124
 
117
125
  // ---------------------------------------------------------------
package/lib/export-pdf.js CHANGED
@@ -229,7 +229,6 @@ export async function run(opts = {}) {
229
229
  // Summary
230
230
  console.log("\u2501".repeat(30));
231
231
  console.log(`Exported: ${success} Failed: ${failure}`);
232
- if (failure > 0) {
233
- process.exit(1);
234
- }
232
+ // Force exit to ensure all child processes (server, npx wrappers) are cleaned up.
233
+ process.exit(failure > 0 ? 1 : 0);
235
234
  }
package/lib/init.js CHANGED
@@ -126,17 +126,13 @@ export async function run(opts) {
126
126
  );
127
127
  console.log(" Created CLAUDE.md");
128
128
 
129
- // 9. .claude/ directory (commands + settings)
129
+ // 9. .claude/ directory (skills + settings)
130
130
  const claudeDir = path.join(targetDir, ".claude");
131
- const commandsDir = path.join(claudeDir, "commands");
132
- fs.mkdirSync(commandsDir, { recursive: true });
133
- const scaffoldCommandsDir = path.join(scaffoldDir, "claude-commands");
134
- for (const file of fs.readdirSync(scaffoldCommandsDir)) {
135
- fs.copyFileSync(
136
- path.join(scaffoldCommandsDir, file),
137
- path.join(commandsDir, file)
138
- );
139
- }
131
+ fs.mkdirSync(claudeDir, { recursive: true });
132
+ copyDir(
133
+ path.join(scaffoldDir, "claude-skills"),
134
+ path.join(claudeDir, "skills")
135
+ );
140
136
  fs.copyFileSync(
141
137
  path.join(scaffoldDir, "claude-settings.json"),
142
138
  path.join(claudeDir, "settings.json")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lazyslides",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Slide decks with native agentic AI integration",
5
5
  "license": "MIT",
6
6
  "author": "Chris Tietz",
@@ -61,7 +61,8 @@
61
61
  "@tailwindcss/cli": "4.1.18",
62
62
  "concurrently": "^9.0.0",
63
63
  "tailwindcss": "4.1.18",
64
- "vitest": "^4.1.2"
64
+ "vite": "^7.3.2",
65
+ "vitest": "^4.1.5"
65
66
  },
66
67
  "scripts": {
67
68
  "dev": "node cli.js validate && concurrently \"pnpm:watch:*\"",
@@ -1,3 +1,18 @@
1
+ ---
2
+ name: add-slide
3
+ description: >
4
+ Guides adding a new slide to an existing LazySlides presentation —
5
+ picks template, gathers content, inserts at the right position, and validates.
6
+ when_to_use: >
7
+ Use when the user wants to add, insert, or append a slide to an existing presentation.
8
+ allowed-tools:
9
+ - Read
10
+ - Edit
11
+ - Bash
12
+ user-invocable: true
13
+ effort: medium
14
+ ---
15
+
1
16
  # Add Slide
2
17
 
3
18
  You are helping the user add a new slide to an existing presentation.
@@ -1,3 +1,20 @@
1
+ ---
2
+ name: add-template
3
+ description: >
4
+ Guides creating a custom Nunjucks slide template for a LazySlides project,
5
+ including the .njk file structure and any required CSS.
6
+ when_to_use: >
7
+ Use when the user wants to create a new slide template that doesn't exist
8
+ in the built-in set of 19 templates.
9
+ allowed-tools:
10
+ - Read
11
+ - Write
12
+ - Edit
13
+ - Bash
14
+ user-invocable: true
15
+ effort: high
16
+ ---
17
+
1
18
  # Add Template
2
19
 
3
20
  You are helping the user create a custom slide template for their LazySlides project.
@@ -1,3 +1,18 @@
1
+ ---
2
+ name: add-theme
3
+ description: >
4
+ Guides creating a custom CSS theme for a LazySlides project, including
5
+ color palette, typography, footer branding, and theater background.
6
+ when_to_use: >
7
+ Use when the user wants to create or apply a custom visual theme to their presentation.
8
+ allowed-tools:
9
+ - Read
10
+ - Write
11
+ - Bash
12
+ user-invocable: true
13
+ effort: medium
14
+ ---
15
+
1
16
  # Add Theme
2
17
 
3
18
  You are helping the user create a custom CSS theme for their LazySlides project.
@@ -1,3 +1,19 @@
1
+ ---
2
+ name: create-outline
3
+ description: >
4
+ Helps build a structured presentation outline before generating YAML —
5
+ covers audience, purpose, section structure, and per-slide content sketches.
6
+ when_to_use: >
7
+ Use when the user wants to plan a presentation before writing slides,
8
+ or when starting a new deck without an existing outline.
9
+ allowed-tools:
10
+ - Read
11
+ - Write
12
+ - Bash
13
+ user-invocable: true
14
+ effort: medium
15
+ ---
16
+
1
17
  # Create Outline
2
18
 
3
19
  You are helping the user create a structured outline before generating presentation YAML.
@@ -1,3 +1,19 @@
1
+ ---
2
+ name: new-presentation
3
+ description: >
4
+ Full guided workflow for creating a LazySlides presentation from scratch —
5
+ gathers requirements, builds an outline, maps templates, and generates index.md.
6
+ when_to_use: >
7
+ Use when the user wants to create a new presentation or start a new deck from scratch.
8
+ allowed-tools:
9
+ - Read
10
+ - Write
11
+ - Edit
12
+ - Bash
13
+ user-invocable: true
14
+ effort: high
15
+ ---
16
+
1
17
  # Create New Presentation
2
18
 
3
19
  You are helping the user create a new presentation in this Eleventy + Reveal.js presentation system.
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: pdf-export
3
+ description: >
4
+ How to export a LazySlides presentation to PDF.
5
+ Covers the command, pipeline, known hang causes, how to verify the pipeline
6
+ with the test fixture, and debugging steps when export fails.
7
+ when_to_use: >
8
+ Use whenever the user asks to "export", "make", "generate", or "create"
9
+ a PDF of a presentation, or when PDF export fails or hangs.
10
+ allowed-tools:
11
+ - Bash
12
+ - Read
13
+ effort: medium
14
+ ---
15
+
16
+ # LazySlides PDF Export
17
+
18
+ ## Command
19
+
20
+ From the project root:
21
+
22
+ ```bash
23
+ pnpm run pdf <presentation-name> # single presentation
24
+ pnpm run pdf # all presentations (skips _-prefixed dirs)
25
+ ```
26
+
27
+ Output lands in `_pdfs/<presentation-name>.pdf`.
28
+
29
+ ## Pipeline (what the script actually does)
30
+
31
+ 1. `pnpm run build` — validate, build CSS, run eleventy. Builds **all** presentations.
32
+ 2. Spawn `npx eleventy --serve --port 4100` as a child.
33
+ 3. Poll `http://127.0.0.1:4100/` until the server responds (60s timeout).
34
+ 4. For each target presentation: `npx decktape reveal --size 1920x1080 --pause 1000 --load-pause 2000 http://127.0.0.1:4100/presentations/<name>/?pdf _pdfs/<name>.pdf`.
35
+ 5. Kill the server, print summary.
36
+
37
+ ## Known gotcha: eleventy doesn't always exit cleanly
38
+
39
+ After writing files, the eleventy build process sometimes stays alive with 0% CPU — a lingering async handle (d2 WASM worker, chokidar, etc.) keeps the event loop open.
40
+
41
+ **The hardened script handles this** via an idle-timeout: if the build child emits no stdout for 15s, we force-kill and proceed. You'll see:
42
+
43
+ ```
44
+ Build child idle for 15s — assuming done and force-exiting.
45
+ ```
46
+
47
+ That line is expected and harmless. The `_site/` has already been written.
48
+
49
+ ## Verifying the pipeline is healthy
50
+
51
+ There's a one-slide smoke-test presentation at `presentations/_test-pdf/`. To confirm the export pipeline works in isolation:
52
+
53
+ ```bash
54
+ pnpm run pdf _test-pdf
55
+ ```
56
+
57
+ If that produces `_pdfs/_test-pdf.pdf`, the pipeline is fine. Any subsequent failure on a real deck is deck-specific — check that deck's content, images, or diagrams.
58
+
59
+ ## Debugging a failure
60
+
61
+ 1. **Nothing visible happens**: decktape's stdout is inherited — you should see `Printing slide 1/N…` live. If you don't, the build or server-start phase stalled.
62
+ 2. **Process leftovers**: `ps aux | grep -E "lazyslides|eleventy|decktape" | grep -v grep` — kill anything stale before retrying.
63
+ 3. **Port 4100 in use**: `lsof -nP -iTCP:4100`. Kill the holder.
64
+ 4. **Do NOT run `pnpm run dev` first** — `pdf` spawns its own server on port 4100 (vs 8080 for dev), but leftover dev-server processes can confuse things.
65
+ 5. **Decktape fails with a clear exit code** — the script surfaces it. Common causes: slide HTML didn't render, an image URL is unreachable, or a d2 diagram failed.
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: presentation-design
3
+ description: >
4
+ Apply when creating, refining, or reviewing LazySlides presentations.
5
+ Guides visual hierarchy, template selection, content density, motion
6
+ strategy, and theme usage for distinctive, professional slide decks.
7
+ when_to_use: >
8
+ Activate for any request involving slide creation, deck improvement, template
9
+ selection, visual design decisions, or content structure in a LazySlides project.
10
+ user-invocable: false
11
+ allowed-tools:
12
+ - Read
13
+ effort: low
14
+ ---
15
+
16
+ # Presentation Design Skill
17
+
18
+ ## 1. Design Thinking Process
19
+
20
+ Before generating YAML, choose an aesthetic direction based on the audience and content:
21
+
22
+ | Direction | Best For | Theme Combo | Transition |
23
+ |-----------|----------|-------------|------------|
24
+ | Minimal/Clean | Data-heavy, technical | `default` or `corporate` | `fade` |
25
+ | Bold/Dramatic | Keynotes, product launches | `midnight` or `theme: black` | `zoom` for reveals, `slide` elsewhere |
26
+ | Warm/Inviting | Training, culture, onboarding | `sunset` or `forest` | `slide` |
27
+ | Corporate/Professional | Board decks, strategy | `corporate` | `fade` |
28
+ | Editorial/Magazine | Thought leadership, creative | `default` | `convex` |
29
+
30
+ ## 2. Visual Hierarchy
31
+
32
+ Structure every deck with this arc:
33
+
34
+ 1. **Title slide** (template: `title`) — establish brand and topic
35
+ 2. **Agenda** (template: `agenda`) — orient the audience (optional for <8 slides)
36
+ 3. **Section dividers** (template: `section`) — breathing room between topics
37
+ 4. **Evidence slides** — mix of `content`, `metrics`, `comparison`, `split`
38
+ 5. **Summary/Close** — `center` with a key takeaway, or `title` reprise
39
+
40
+ Rules:
41
+ - One idea per slide
42
+ - Title slides should have 2-6 word headlines
43
+ - Section dividers every 4-7 slides in long decks (>12 slides)
44
+ - End with impact: a bold statement, a call to action, or a key metric
45
+
46
+ ## 3. Template Selection Strategy
47
+
48
+ **Never use 3+ of the same template in a row.** Alternate between text-heavy and visual templates:
49
+
50
+ | Purpose | Template Options |
51
+ |---------|-----------------|
52
+ | Argument building | `content` with `fragment: fade-up` |
53
+ | Visual evidence | `split`, `split-wide`, `center` (with image) |
54
+ | Data points | `metrics`, `table`, `comparison` |
55
+ | Narrative flow | `timeline`, `funnel` |
56
+ | Impact statement | `quote`, `hero`, `center` (text only) |
57
+ | Code demonstration | `code` |
58
+ | Side-by-side comparison | `columns`, `comparison` |
59
+
60
+ **Emotional arc**: Open with impact (hero/title) -> build with evidence (content/metrics/comparison) -> close with aspiration (quote/center/hero)
61
+
62
+ ## 4. Content Density Rules
63
+
64
+ | Element | Guideline |
65
+ |---------|-----------|
66
+ | Headlines | 2-6 words, action-oriented |
67
+ | Bullet text | Max 12 words per bullet |
68
+ | Bullets per slide | 3-5 items |
69
+ | Metrics | 3 for visual balance (2 or 4 acceptable) |
70
+ | Code blocks | Max 10 visible lines |
71
+ | Quote text | Max 2 sentences |
72
+ | Nested lists | Max 2 levels deep |
73
+
74
+ If a slide exceeds these limits, split it into two slides.
75
+
76
+ ## 5. Motion & Animation Strategy
77
+
78
+ ### Use fragments for:
79
+ - Argument building: reveal bullets one-by-one (`fragment: fade-up`)
80
+ - Metric reveals: show numbers progressively (`fragment: fade-in`)
81
+ - Comparison reveals: expose rows one at a time (`fragment: fade-up`)
82
+ - Progressive disclosure in training content
83
+
84
+ ### Do NOT use fragments for:
85
+ - Every slide (causes pacing fatigue)
86
+ - Simple lists with <3 items
87
+ - Decorative purposes
88
+ - Section dividers or title slides
89
+
90
+ ### Use auto-animate for:
91
+ - Before/after comparisons (matching `data_id` on items)
92
+ - Progressive detail — start simple, add complexity
93
+ - Code evolution — show how code changes step by step
94
+
95
+ ### Per-slide transitions:
96
+ - `transition: zoom` — only for dramatic reveals (use sparingly, max 2 per deck)
97
+ - `transition: fade` — smooth narrative flow, section transitions
98
+ - `transition: none` — rapid-fire comparison between similar slides
99
+ - Default `slide` transition works well for most slides
100
+
101
+ ## 6. Theme & Color Usage
102
+
103
+ ### Metric colors tell a story:
104
+ - `mint` — positive outcomes, growth, success
105
+ - `coral` — negative outcomes, problems, risks
106
+ - `amber` — warnings, caveats, things to watch
107
+ - `icy` — neutral data, context, baseline
108
+
109
+ ### Hero slides:
110
+ - `color` should match the theme's mood (dark for midnight, warm for sunset)
111
+ - Use `background_image` for photographic hero slides
112
+ - Use `background_gradient` for abstract/geometric backgrounds
113
+
114
+ ### Comparison highlights:
115
+ - `highlight: right` (default) — right column is the recommendation
116
+ - `highlight: left` — left column is preferred
117
+ - `highlight: none` — neutral comparison
118
+
119
+ ### Background enhancements:
120
+ - `background_color` on section dividers for visual separation
121
+ - `background_gradient` for mood transitions between sections
122
+ - `background_image` sparingly — max 2-3 per deck
123
+
124
+ ## 7. Anti-Patterns to Flag
125
+
126
+ When reviewing presentations, flag these issues:
127
+
128
+ - **Wall of text**: Any slide with >100 words of body content
129
+ - **Template monotony**: 3+ consecutive slides with the same template
130
+ - **Missing section dividers**: Decks >8 slides without any `section` templates
131
+ - **Generic titles**: "Overview", "Details", "Summary" — titles should be specific
132
+ - **Orphaned sections**: A `section` divider followed by only 1 content slide
133
+ - **Fragment overuse**: More than 50% of slides using fragments
134
+ - **Metric overload**: More than 4 metrics on a single slide
135
+ - **Missing speaker notes**: Important slides without `notes:` field
136
+ - **Image-heavy without alt text**: `image` fields without `image_alt`
@@ -1,3 +1,18 @@
1
+ ---
2
+ name: refine-slides
3
+ description: >
4
+ Reviews and improves an existing LazySlides presentation — checks structure,
5
+ template variety, content density, design anti-patterns, and applies approved changes.
6
+ when_to_use: >
7
+ Use when the user wants to improve, polish, review, or fix an existing presentation.
8
+ allowed-tools:
9
+ - Read
10
+ - Edit
11
+ - Bash
12
+ user-invocable: true
13
+ effort: medium
14
+ ---
15
+
1
16
  # Refine Slides
2
17
 
3
18
  You are helping the user improve an existing presentation.
@@ -16,10 +31,18 @@ You are helping the user improve an existing presentation.
16
31
 
17
32
  Analyze and report:
18
33
  - **Slide count** — is it appropriate for the estimated duration?
19
- - **Template diversity** — are templates varied or repetitive? (e.g., 10 `content` slides in a row)
34
+ - **Template diversity** — are templates varied or repetitive? (e.g., 3+ `content` slides in a row)
20
35
  - **Visual rhythm** — is there a good mix of text-heavy and visual slides?
21
36
  - **Section structure** — are `section` dividers used to organize the flow?
22
37
  - **Notes coverage** — which slides are missing speaker notes?
38
+ - **Design quality** — check against the presentation-design skill anti-patterns:
39
+ - Wall of text (>100 words on a slide)
40
+ - Template monotony (3+ consecutive same template)
41
+ - Missing section dividers in decks >8 slides
42
+ - Generic titles ("Overview", "Details")
43
+ - Fragment overuse (>50% of slides)
44
+ - Missing alt text on images
45
+ - **Animation strategy** — suggest where `fragment`, `auto_animate`, or per-slide `transition` would improve the narrative
23
46
 
24
47
  ## Step 3: Content Review
25
48
 
@@ -1,3 +1,20 @@
1
+ ---
2
+ name: research-topic
3
+ description: >
4
+ Researches a topic to gather statistics, quotes, comparisons, and case studies
5
+ for a data-driven LazySlides presentation, then saves findings as research.md.
6
+ when_to_use: >
7
+ Use when the user wants to gather data, statistics, or supporting evidence
8
+ for a presentation topic.
9
+ allowed-tools:
10
+ - WebSearch
11
+ - WebFetch
12
+ - Read
13
+ - Write
14
+ user-invocable: true
15
+ effort: high
16
+ ---
17
+
1
18
  # Research Topic
2
19
 
3
20
  You are helping the user research a topic to build a data-driven presentation.
@@ -1,3 +1,18 @@
1
+ ---
2
+ name: validate
3
+ description: >
4
+ Runs LazySlides YAML validation, interprets errors and warnings,
5
+ proposes fixes, and applies approved corrections.
6
+ when_to_use: >
7
+ Use when the user wants to validate, check, or fix their presentation YAML.
8
+ allowed-tools:
9
+ - Bash
10
+ - Read
11
+ - Edit
12
+ user-invocable: true
13
+ effort: low
14
+ ---
15
+
1
16
  # Validate Presentations
2
17
 
3
18
  You are helping the user validate their presentation YAML and fix any issues.