create-marp-presentation 1.2.0 → 1.2.1

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.
@@ -0,0 +1,136 @@
1
+ # Theme Add Command Fix Design
2
+
3
+ **Date:** 2026-02-27
4
+ **Status:** Approved
5
+ **Author:** Claude Code
6
+
7
+ ## Problem
8
+
9
+ When running `npm run theme:add` in a generated project, the theme list shows hundreds of CSS files from `node_modules` instead of only valid themes. This happens because:
10
+
11
+ 1. `template/scripts/theme-cli.js` uses `templatePath = path.join(__dirname, '..')` which includes `node_modules/`
12
+ 2. `ThemeResolver._findCssFiles()` recursively finds ALL `.css` files without filtering
13
+ 3. Files from packages like `@inquirer`, `picocss` appear as "themes"
14
+
15
+ ## Root Cause
16
+
17
+ The generated project's `theme:add` command tries to scan themes from the template directory, which includes `node_modules/`. The metapackage has the correct theme library at `themes/` but the local script doesn't know about it.
18
+
19
+ ## Solution
20
+
21
+ Use the metapackage's existing `theme:add` handler instead of local implementation. The metapackage already has:
22
+ - Correct `themesLibraryPath` pointing to the theme library
23
+ - `AddThemesCommand` that properly scans only theme files
24
+ - Working conflict resolution and VSCode integration
25
+
26
+ ## Architecture
27
+
28
+ ### Before
29
+
30
+ ```
31
+ Generated Project
32
+ └─ npm run theme:add
33
+ └─ template/scripts/theme-cli.js (add command)
34
+ └─ templatePath = ../ (includes node_modules!)
35
+ └─ ThemeResolver scans ALL CSS files ❌
36
+ ```
37
+
38
+ ### After
39
+
40
+ ```
41
+ Generated Project
42
+ └─ npm run theme:add
43
+ └─ npx create-marp-presentation theme:add .
44
+ └─ index.js → handleThemeAdd()
45
+ └─ themesLibraryPath = /path/to/metapackage/themes ✓
46
+ └─ AddThemesCommand scans only themes ✓
47
+ ```
48
+
49
+ ## Implementation
50
+
51
+ ### 1. template/package.json
52
+
53
+ Add new script:
54
+
55
+ ```json
56
+ {
57
+ "scripts": {
58
+ "theme:add": "npx create-marp-presentation theme:add .",
59
+ "theme": "node scripts/theme-cli.js"
60
+ }
61
+ }
62
+ ```
63
+
64
+ ### 2. template/scripts/theme-cli.js
65
+
66
+ Remove the `add` command:
67
+
68
+ ```javascript
69
+ // DELETE: addThemes() function
70
+ // DELETE: case 'add': from switch statement
71
+ // UPDATE: help message (remove theme:add from local commands)
72
+ ```
73
+
74
+ ### 3. index.js (metapackage)
75
+
76
+ No changes needed - `theme:add` handler already exists and works correctly.
77
+
78
+ ### 4. tests/integration/theme-cli.test.js
79
+
80
+ Add integration test:
81
+
82
+ ```javascript
83
+ test('theme:add command works in generated project', async () => {
84
+ const localPackagePath = path.join(__dirname, '../..');
85
+
86
+ const project = await createTempProject();
87
+
88
+ const result = spawnSync(
89
+ 'node',
90
+ [path.join(localPackagePath, 'index.js'), 'theme:add', project.path, 'beam'],
91
+ { cwd: project.path }
92
+ );
93
+
94
+ expect(result.status).toBe(0);
95
+
96
+ const themePath = path.join(project.path, 'themes', 'beam', 'beam.css');
97
+ expect(fs.existsSync(themePath)).toBe(true);
98
+
99
+ // Verify no node_modules files in themes/
100
+ const themes = fs.readdirSync(path.join(project.path, 'themes'), { recursive: true });
101
+ const cssFiles = themes.filter(f => f.endsWith('.css'));
102
+ expect(cssFiles).not.toContain('inquirer.css');
103
+ expect(cssFiles).not.toContain('picocss.min.css');
104
+ });
105
+ ```
106
+
107
+ ## Why This Works
108
+
109
+ 1. **Correct theme source**: Metapackage's `themesLibraryPath` points to the isolated `themes/` folder
110
+ 2. **No node_modules scanning**: Theme files are separate from dependencies
111
+ 3. **Consistent behavior**: Same code path as project creation
112
+ 4. **No code duplication**: Single implementation in metapackage
113
+
114
+ ## Error Handling
115
+
116
+ | Scenario | Behavior |
117
+ |----------|----------|
118
+ | npx not available | Error: "Node.js required to run this command" |
119
+ | Metapackage unreachable | Error: "Unable to reach create-marp-presentation. Check your internet connection." |
120
+ | Not a Marp project | Error: "Run this command from a Marp project directory" |
121
+ | No themes available | Message: "No themes available to add" |
122
+
123
+ ## Files to Modify
124
+
125
+ 1. `template/package.json` - Add `theme:add` script
126
+ 2. `template/scripts/theme-cli.js` - Remove `add` command
127
+ 3. `tests/integration/theme-cli.test.js` - Add integration test
128
+
129
+ ## User Impact
130
+
131
+ **Breaking change:** None - users get the same functionality, but it actually works correctly now.
132
+
133
+ **Benefits:**
134
+ - Theme list shows only valid themes
135
+ - Faster (no scanning thousands of irrelevant files)
136
+ - Consistent with project creation flow
@@ -0,0 +1,353 @@
1
+ # Theme Add Command Fix Implementation Plan
2
+
3
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
+
5
+ **Goal:** Fix `npm run theme:add` showing node_modules CSS files instead of valid themes by delegating to metapackage handler.
6
+
7
+ **Architecture:** Replace local `theme:add` implementation with `npx create-marp-presentation theme:add .` command that uses metapackage's correct theme library path.
8
+
9
+ **Tech Stack:** Node.js, npm scripts, jest for testing
10
+
11
+ **Reference design:** `docs/plans/2026-02-27-theme-add-fix-design.md`
12
+
13
+ ---
14
+
15
+ ## Task 1: Add theme:add script to template/package.json
16
+
17
+ **Files:**
18
+ - Modify: `template/package.json`
19
+
20
+ **Step 1: Read current template/package.json**
21
+
22
+ Read the file to understand current script structure.
23
+
24
+ **Step 2: Add theme:add script**
25
+
26
+ Add the new script to the scripts section:
27
+
28
+ ```json
29
+ {
30
+ "scripts": {
31
+ "theme:add": "npx create-marp-presentation theme:add .",
32
+ "theme": "node scripts/theme-cli.js",
33
+ "dev": "marp --server --html",
34
+ "build:html": "marp --html --allow-local-files",
35
+ "build:pdf": "marp --pdf --allow-local-files && npm run copy:static",
36
+ "build:pptx": "marp --pptx --allow-local-files && npm run copy:static",
37
+ "build:all": "npm run build:html && npm run build:pdf && npm run build:pptx",
38
+ "copy:static": "node scripts/copy-static.js",
39
+ "clean": "rimraf output"
40
+ }
41
+ }
42
+ ```
43
+
44
+ **Step 3: Verify JSON syntax**
45
+
46
+ Run: `node -e "JSON.parse(require('fs').readFileSync('template/package.json'))"`
47
+ Expected: No syntax errors
48
+
49
+ **Step 4: Commit**
50
+
51
+ ```bash
52
+ git add template/package.json
53
+ git commit -m "feat: add theme:add script to template package.json"
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Task 2: Remove add command from template/scripts/theme-cli.js
59
+
60
+ **Files:**
61
+ - Modify: `template/scripts/theme-cli.js`
62
+
63
+ **Step 1: Read theme-cli.js**
64
+
65
+ Read the file to locate:
66
+ - `addThemes()` function (around line 80-160)
67
+ - `case 'add':` in switch statement (around line 240)
68
+ - Help message
69
+
70
+ **Step 2: Remove addThemes() function**
71
+
72
+ Delete the entire `async function addThemes()` function.
73
+
74
+ **Step 3: Remove add case from switch**
75
+
76
+ Find and remove from the switch statement:
77
+ ```javascript
78
+ case 'add':
79
+ await addThemes(args.filter(a => !a.startsWith('--')));
80
+ break;
81
+ ```
82
+
83
+ **Step 4: Update help message**
84
+
85
+ Remove `add [theme...]` from the help output. Updated help should show:
86
+
87
+ ```
88
+ Commands:
89
+ list List installed themes
90
+ create <name> Create a new theme
91
+ set <theme> Set active theme in presentation.md
92
+ switch <theme> Alias for 'set' - change active theme
93
+ sync Sync installed themes to VSCode settings
94
+ help Show this help message
95
+ ```
96
+
97
+ **Step 5: Update usage examples**
98
+
99
+ Remove examples showing `theme add` and add note about `theme:add`:
100
+
101
+ ```
102
+ Run "npm run theme:add" to add themes from the theme library.
103
+ ```
104
+
105
+ **Step 6: Verify syntax**
106
+
107
+ Run: `node template/scripts/theme-cli.js`
108
+ Expected: Shows help (no errors)
109
+
110
+ **Step 7: Commit**
111
+
112
+ ```bash
113
+ git add template/scripts/theme-cli.js
114
+ git commit -m "refactor: remove add command from theme-cli.js, use metapackage handler"
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Task 3: Add integration test for theme:add command
120
+
121
+ **Files:**
122
+ - Modify: `tests/integration/theme-cli.test.js`
123
+
124
+ **Step 1: Read existing integration test file**
125
+
126
+ Understand test patterns and fixtures used.
127
+
128
+ **Step 2: Write failing test**
129
+
130
+ Add to `tests/integration/theme-cli.test.js`:
131
+
132
+ ```javascript
133
+ describe('theme:add command', () => {
134
+ test('adds themes to generated project using metapackage handler', async () => {
135
+ const { createTempProject } = require('../helpers/temp-project');
136
+ const { spawnSync } = require('child_process');
137
+ const path = require('path');
138
+ const fs = require('fs');
139
+
140
+ const localPackagePath = path.join(__dirname, '../..');
141
+
142
+ // Create a temporary project
143
+ const project = await createTempProject();
144
+
145
+ // Run theme:add using local metapackage
146
+ const result = spawnSync(
147
+ 'node',
148
+ [path.join(localPackagePath, 'index.js'), 'theme:add', project.path, 'beam'],
149
+ { cwd: project.path }
150
+ );
151
+
152
+ // Command should succeed
153
+ expect(result.status).toBe(0);
154
+ expect(result.stderr.toString()).toBe('');
155
+
156
+ // Theme should be copied
157
+ const themePath = path.join(project.path, 'themes', 'beam', 'beam.css');
158
+ expect(fs.existsSync(themePath)).toBe(true);
159
+
160
+ // Verify no node_modules files in themes directory
161
+ const themesDir = path.join(project.path, 'themes');
162
+ const allFiles = getAllFiles(themesDir);
163
+ const cssFiles = allFiles.filter(f => f.endsWith('.css'));
164
+
165
+ // These files should NOT exist (they're from node_modules)
166
+ const badFiles = cssFiles.filter(f =>
167
+ f.includes('inquirer') ||
168
+ f.includes('picocss') ||
169
+ f.includes('node_modules')
170
+ );
171
+
172
+ expect(badFiles).toHaveLength(0);
173
+
174
+ // Clean up
175
+ fs.rmSync(project.path, { recursive: true, force: true });
176
+ });
177
+
178
+ function getAllFiles(dirPath, arrayOfFiles = []) {
179
+ const files = fs.readdirSync(dirPath);
180
+ files.forEach(file => {
181
+ const filePath = path.join(dirPath, file);
182
+ if (fs.statSync(filePath).isDirectory()) {
183
+ getAllFiles(filePath, arrayOfFiles);
184
+ } else {
185
+ arrayOfFiles.push(filePath);
186
+ }
187
+ });
188
+ return arrayOfFiles;
189
+ }
190
+ });
191
+ ```
192
+
193
+ **Step 3: Run test to verify it fails (theme:add not yet working)**
194
+
195
+ Run: `npm test -- tests/integration/theme-cli.test.js -t "theme:add command"`
196
+ Expected: May fail or pass depending on current state
197
+
198
+ **Step 4: If test passes due to Tasks 1-2, commit test**
199
+
200
+ ```bash
201
+ git add tests/integration/theme-cli.test.js
202
+ git commit -m "test: add integration test for theme:add command"
203
+ ```
204
+
205
+ **Step 5: If test fails, debug and fix**
206
+
207
+ Check:
208
+ - Is `npx` available?
209
+ - Is `theme:add` script in package.json?
210
+ - Is the project path correct?
211
+
212
+ ---
213
+
214
+ ## Task 4: Manual verification test
215
+
216
+ **Files:**
217
+ - None (manual testing)
218
+
219
+ **Step 1: Create a test project**
220
+
221
+ Run: `node index.js test-theme-add --path /tmp`
222
+
223
+ **Step 2: Navigate to project**
224
+
225
+ Run: `cd /tmp/test-theme-add`
226
+
227
+ **Step 3: Run theme:add interactively**
228
+
229
+ Run: `npm run theme:add`
230
+
231
+ Expected:
232
+ - Prompts with theme list (beam, default-clean, etc.)
233
+ - NOT showing node_modules files
234
+ - Selected theme copies to themes/
235
+
236
+ **Step 4: Verify theme was added**
237
+
238
+ Run: `cat themes/beam/beam.css | head -5`
239
+ Expected: CSS file with `/* @theme beam */` comment
240
+
241
+ **Step 5: Run theme:add with specific theme**
242
+
243
+ Run: `npm run theme:add marpx`
244
+
245
+ Expected: marpx theme added
246
+
247
+ **Step 6: Clean up**
248
+
249
+ Run: `rm -rf /tmp/test-theme-add`
250
+
251
+ **Step 7: Document findings**
252
+
253
+ If tests pass, no commit needed. If issues found, create fix commits.
254
+
255
+ ---
256
+
257
+ ## Task 5: Update CLAUDE.md documentation
258
+
259
+ **Files:**
260
+ - Modify: `CLAUDE.md`
261
+
262
+ **Step 1: Read current CLAUDE.md**
263
+
264
+ Find sections about theme management.
265
+
266
+ **Step 2: Update theme:add documentation**
267
+
268
+ Add note about new implementation:
269
+
270
+ ```markdown
271
+ ### Theme Management in Generated Projects
272
+
273
+ Generated projects use `npm run theme:add` to add themes:
274
+
275
+ \`\`\`bash
276
+ npm run theme:add # Interactive theme selection
277
+ npm run theme:add beam marpx # Add specific themes
278
+ \`\`\`
279
+
280
+ This delegates to the metapackage's `theme:add` handler, which has access
281
+ to the full theme library.
282
+ ```
283
+
284
+ **Step 3: Commit**
285
+
286
+ ```bash
287
+ git add CLAUDE.md
288
+ git commit -m "docs: update theme:add documentation"
289
+ ```
290
+
291
+ ---
292
+
293
+ ## Task 6: Full test suite verification
294
+
295
+ **Files:**
296
+ - None (verification)
297
+
298
+ **Step 1: Run all tests**
299
+
300
+ Run: `npm test`
301
+
302
+ Expected: All tests pass
303
+
304
+ **Step 2: Run integration tests specifically**
305
+
306
+ Run: `npm test -- tests/integration/`
307
+
308
+ Expected: All integration tests pass
309
+
310
+ **Step 3: Run CLI tests**
311
+
312
+ Run: `npm test -- tests/cli.test.js`
313
+
314
+ Expected: All CLI tests pass
315
+
316
+ **Step 4: If any test fails, debug and fix**
317
+
318
+ Use `superpowers:systematic-debugging` skill if needed.
319
+
320
+ **Step 5: Final summary commit**
321
+
322
+ ```bash
323
+ git commit --allow-empty -m "fix: theme:add command now uses metapackage handler
324
+
325
+ - Fixes theme list showing node_modules CSS files
326
+ - template/package.json: add theme:add script using npx
327
+ - template/scripts/theme-cli.js: remove local add command
328
+ - Integration test verifies only valid themes are shown
329
+ "
330
+ ```
331
+
332
+ ---
333
+
334
+ ## Verification Checklist
335
+
336
+ After completing all tasks:
337
+
338
+ - [ ] `npm run theme:add` works in generated project
339
+ - [ ] Theme list shows only valid themes (beam, marpx, etc.)
340
+ - [ ] No files from node_modules appear in theme list
341
+ - [ ] Selected themes are copied to project/themes/
342
+ - [ ] All unit tests pass
343
+ - [ ] All integration tests pass
344
+ - [ ] CLAUDE.md documentation updated
345
+ - [ ] Manual testing confirms fix works
346
+
347
+ ---
348
+
349
+ ## Notes
350
+
351
+ - The metapackage's `index.js` already has `theme:add` handler - no changes needed there
352
+ - This fix ensures consistency between project creation and theme addition
353
+ - The `npx` command uses the published version; for development testing, the integration test uses the local index.js
@@ -0,0 +1,5 @@
1
+ # Что не забыть сделать в механизме тем
2
+ - [X] Порефакрторить add-themes-cli.js и create-project.ts убрать дублирующийся код. Минимизировать код. Обновить тесты.
3
+ - [x] Провести ручное тестирование команды themes:add в проекте.
4
+ - [ ] Починить дефект с вставкой в settings.json css файлов в системных тем.
5
+ - [x] Написать документацию.
@@ -0,0 +1,49 @@
1
+ # Механизм работы тем
2
+
3
+ Тема - сущность, котрая определяет все стили презентации и указывается в самой презентации в front matter заголовке.
4
+
5
+ Общие атрибуты для всех тем:
6
+ - **Имя темы** - обязательно. Уникальное имя на весь проект.
7
+
8
+
9
+ ## Типы тем
10
+ - **Системная** - все стили этой темы заданы внутри marp, для них не требуется в общем случае никаких css файлов. Их 3 штуки: `default`, `gaia`, `uncover`.
11
+ - **Пользовательская** - для пользовательской темы, обязательно задается 1 или несколько css файлов, которые могут как полностью определить с нуля всю тему, так и сделать импорт уже существующей темы (системной или ользовательской) и доопределить или переопределить стили родительской темы.
12
+
13
+ У каждой пользовательской темы есть:
14
+ - **Имя темы** - обязательно.
15
+ - **Файлы стилей** - css файлы, в которых определяется поведение и внешний вид. Для пользовательской темы обязательно должен быть 1 css файл, а в общем случае может быть несколько файлов, которые выстроены в цепочку импортов (зависимостей).
16
+
17
+
18
+ ## Зависимости тем
19
+ Темы могут зависеть друг от друга (через имопрт в css (@import 'gaia')). Это полезно, когда нужно на основе какой-то темы построить новую - доопределив или переопределив в ней стили. Импорт происходит по имени темы
20
+
21
+
22
+ ### Примеры зависимостей
23
+ - `dark` (dark.css, тип: пользовательская) -> `gaia` (css встроен в marp,тип: системная).
24
+ - `einstein` (einstein.css, тип: пользовательская) -> `marpx` (marpx.css, тип: пользовательская) -> `default` (css встроен в marp, тип: системная)
25
+ - `dracula` (dracula.css, тип: пользовательская). Нет зависимостей - тема полностью с нуля разработана пользователем.
26
+
27
+ ## Управление темами
28
+
29
+ ### При создании проекта
30
+ При создании проекта пользователь должен иметь возможность выбрать преднастроенные в шаблоне пользовательские темы. Это множественный выбор тем, которые добавятся в проект после генерации.
31
+
32
+ Система должна в интерактивном режиме через CLI запросить список тем, добавляемых в проект. В шаблоне проекта нужно предусмотреть пополняемую структуру хранения пользовательских тем. Со временем в проекте набор пользовательских тем в шаблоне будет дорабатываться и обновляться.
33
+
34
+ ### Управление темами после создания
35
+ После генерации проекта должны быть CLI инструменты управления темами в проекте. CLI операции:
36
+ - Показать список тем в проекте. Список имен тем.
37
+ - Добавить новую пользовательскую тему самостоятельно. Добавление пользовательской темы. Запрашивается имя. Запрашивается тема-родитель (имя): варианты: без родителя, системная, пользовательская. В зависимости от выбора генерируется шаблон css файла для переопределения.
38
+ - Добавить тему из шаблона. Если пользователь забыл при создании проекта указать какую-то пользовательскую тему из шаблона (или решил после, что ему нужна какая-то новая тема), то у него должна быть возможность это сделать уже в существующем проекте после создания.
39
+ - Добавить css файл в существующую тему. Как мы уже поняли, что тема может состоять из нескольких файлов. Может потребоваться операция добавления в тему файла. Каждая пользовательская тема должна "знать" от каких css файлов она зависит.
40
+
41
+
42
+ ## Интеграция с vscode
43
+
44
+ Во время создания проекта и после при любых операциях с темами в проекте, темы должны автоматически быть интегрированы с VSCode плагином (Marp for VS Code). А именно: все css файлы пользовательских тем проекта должны автоматически быть добавлены в `.vscode/settings.json` для того, чтобы IDE могла "подхватить" эти темы и отобразить слайды.
45
+
46
+
47
+ ## Другие требования
48
+ - CLI команды должны работать в интерактивном режиме. Использовать готовые реализации для этого - не писать с нуля.
49
+ - Весь код должен быть покрыт автотестамии.