create-marp-presentation 1.2.0 → 1.2.2
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/cli/commands/add-themes-cli.js +85 -0
- package/cli/commands/create-project.js +199 -0
- package/cli/utils/file-utils.js +106 -0
- package/cli/utils/prompt-utils.js +89 -0
- package/docs/plans/2025-02-19-marp-template-design.md +207 -0
- package/docs/plans/2025-02-19-marp-template-implementation.md +848 -0
- package/docs/plans/2026-02-20-example-slides-design.md +179 -0
- package/docs/plans/2026-02-20-example-slides-implementation.md +811 -0
- package/docs/plans/2026-02-23-theme-management-design.md +836 -0
- package/docs/plans/2026-02-23-theme-management-implementation.md +3585 -0
- package/docs/plans/2026-02-26-theme-addition-refactoring-design.md +172 -0
- package/docs/plans/2026-02-26-theme-addition-refactoring.md +456 -0
- package/docs/plans/2026-02-27-theme-add-fix-design.md +136 -0
- package/docs/plans/2026-02-27-theme-add-fix.md +353 -0
- package/docs/plans/2026-02-28-conflict-resolution-fix.md +62 -0
- package/docs/plans/TODO.md +5 -0
- package/docs/reqs/themes-requirements.md +49 -0
- package/docs/theme-management.md +261 -0
- package/lib/add-themes-command.js +5 -1
- package/lib/prompts.js +22 -5
- package/lib/theme-manager.js +8 -2
- package/lib/theme-resolver.js +20 -2
- package/package.json +3 -1
- package/themes/beam/beam.css +1 -0
- package/themes/default-clean/default-clean.css +1 -1
- package/themes/gaia-dark/gaia-dark.css +1 -1
- package/themes/marpx/marpx.css +2 -1
- package/themes/marpx/socrates.css +1 -0
- package/themes/uncover-minimal/uncover-minimal.css +1 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Theme Addition Refactoring Design
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-02-26
|
|
4
|
+
**Status:** Approved
|
|
5
|
+
**Author:** Claude Code
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
The theme addition code is duplicated between `create-project.js` (~80 lines) and `add-themes-cli.js` (~120 lines):
|
|
10
|
+
- Identical conflict resolution logic (~30 lines)
|
|
11
|
+
- Similar theme selection patterns
|
|
12
|
+
- VSCode settings handling in both files
|
|
13
|
+
- Active theme selection duplicated
|
|
14
|
+
|
|
15
|
+
This creates maintenance burden and potential for inconsistencies.
|
|
16
|
+
|
|
17
|
+
## Solution
|
|
18
|
+
|
|
19
|
+
Centralize all theme addition logic in `AddThemesCommand` class, making CLI files simple wrappers.
|
|
20
|
+
|
|
21
|
+
## Architecture
|
|
22
|
+
|
|
23
|
+
### Responsibilities
|
|
24
|
+
|
|
25
|
+
| Component | Responsibilities |
|
|
26
|
+
|-----------|------------------|
|
|
27
|
+
| **AddThemesCommand** | Theme selection prompt, conflict detection/resolution, theme copying, VSCode sync |
|
|
28
|
+
| **create-project.js** | Call AddThemesCommand, select active theme from copied themes |
|
|
29
|
+
| **add-themes-cli.js** | Call AddThemesCommand, show summary (no active theme logic) |
|
|
30
|
+
|
|
31
|
+
### Why This Split
|
|
32
|
+
|
|
33
|
+
- **New project**: User expects to choose which theme to use → create-project.js handles active theme
|
|
34
|
+
- **Existing project**: Adding themes shouldn't change active theme → add-themes-cli.js doesn't touch it
|
|
35
|
+
|
|
36
|
+
## AddThemesCommand API
|
|
37
|
+
|
|
38
|
+
### Constructor
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
new AddThemesCommand({
|
|
42
|
+
templatePath, // Path to themes library
|
|
43
|
+
interactive: true // Always true for theme selection
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Execute Method
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
async execute(projectPath, options = {}) {
|
|
51
|
+
// Options:
|
|
52
|
+
// - themes: string[] (optional - skip selection prompt if provided)
|
|
53
|
+
// - skipConflictCheck: boolean (default: false)
|
|
54
|
+
|
|
55
|
+
// Returns:
|
|
56
|
+
return {
|
|
57
|
+
copied: [Theme, ...], // Theme objects that were copied
|
|
58
|
+
skipped: ['theme1'], // Theme names that were skipped
|
|
59
|
+
conflicts: ['theme2'] // Theme names with conflicts
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Internal Flow
|
|
65
|
+
|
|
66
|
+
1. Scan available themes from `templatePath`
|
|
67
|
+
2. If `themes` not provided: prompt user to select themes (using `Prompts.promptThemes()`)
|
|
68
|
+
3. Resolve dependencies via `ThemeResolver.resolveDependencies()`
|
|
69
|
+
4. Check for file conflicts (always runs, finds nothing in new projects)
|
|
70
|
+
5. If conflicts found: prompt for resolution (using `Prompts.promptConflictResolution()`)
|
|
71
|
+
6. Copy themes to project
|
|
72
|
+
7. Update VSCode settings.json with theme paths
|
|
73
|
+
8. Return result
|
|
74
|
+
|
|
75
|
+
## CLI File Usage
|
|
76
|
+
|
|
77
|
+
### create-project.js
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
const command = new AddThemesCommand({
|
|
81
|
+
templatePath: themesLibraryPath
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const { copied } = await command.execute(projectPath);
|
|
85
|
+
|
|
86
|
+
// Select active theme from copied themes
|
|
87
|
+
const themeNames = copied.map(t => t.name);
|
|
88
|
+
const activeTheme = await Prompts.promptActiveTheme(themeNames);
|
|
89
|
+
await ThemeManager.setActiveTheme(projectPath, activeTheme);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### add-themes-cli.js
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
const command = new AddThemesCommand({
|
|
96
|
+
templatePath: themesLibraryPath
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const { copied, skipped, conflicts } = await command.execute(projectPath);
|
|
100
|
+
|
|
101
|
+
// Show summary
|
|
102
|
+
console.log(`Copied: ${copied.map(t => t.name).join(', ')}`);
|
|
103
|
+
if (skipped.length) console.log(`Skipped: ${skipped.join(', ')}`);
|
|
104
|
+
if (conflicts.length) console.log(`Conflicts: ${conflicts.join(', ')}`);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Files to Modify
|
|
108
|
+
|
|
109
|
+
1. **lib/add-themes-command.js** - Add built-in prompts, return Theme objects
|
|
110
|
+
2. **cli/commands/create-project.js** - Remove duplicated code, simplify to ~10 lines
|
|
111
|
+
3. **cli/commands/add-themes-cli.js** - Remove duplicated code and active theme logic
|
|
112
|
+
|
|
113
|
+
## Key Changes
|
|
114
|
+
|
|
115
|
+
### AddThemesCommand
|
|
116
|
+
|
|
117
|
+
- ✅ Built-in theme selection (uses `Prompts.promptThemes()`)
|
|
118
|
+
- ✅ Built-in conflict resolution (uses `Prompts.promptConflictResolution()`)
|
|
119
|
+
- ✅ Always runs conflict checking (harmless in new projects)
|
|
120
|
+
- ✅ Returns Theme objects (not names)
|
|
121
|
+
- ✅ Handles VSCode settings internally
|
|
122
|
+
|
|
123
|
+
### create-project.js
|
|
124
|
+
|
|
125
|
+
- ❌ Remove `askAddThemes()` prompt
|
|
126
|
+
- ❌ Remove `addThemesToProject()` function
|
|
127
|
+
- ❌ Remove VSCode settings update
|
|
128
|
+
- ✅ Keep active theme selection
|
|
129
|
+
|
|
130
|
+
### add-themes-cli.js
|
|
131
|
+
|
|
132
|
+
- ❌ Remove theme selection prompt logic
|
|
133
|
+
- ❌ Remove active theme prompt and setting
|
|
134
|
+
- ❌ Remove VSCode settings update
|
|
135
|
+
- ✅ Keep summary output
|
|
136
|
+
|
|
137
|
+
## Error Handling
|
|
138
|
+
|
|
139
|
+
| Scenario | Behavior |
|
|
140
|
+
|----------|----------|
|
|
141
|
+
| No themes available | Show message, return empty result |
|
|
142
|
+
| User cancels selection | Return empty result |
|
|
143
|
+
| User cancels conflict resolution | Stop, return what was copied so far |
|
|
144
|
+
| Copy errors | Collect and continue, report at end |
|
|
145
|
+
|
|
146
|
+
## Testing
|
|
147
|
+
|
|
148
|
+
### Unit Tests (AddThemesCommand)
|
|
149
|
+
|
|
150
|
+
- Theme selection prompt is called when themes not provided
|
|
151
|
+
- Conflict resolution prompt is called when conflicts exist
|
|
152
|
+
- Returns correct Theme objects
|
|
153
|
+
- VSCode settings updated correctly
|
|
154
|
+
- Empty result returned when user cancels
|
|
155
|
+
|
|
156
|
+
### Integration Tests
|
|
157
|
+
|
|
158
|
+
- create-project: themes added, active theme set correctly
|
|
159
|
+
- add-themes: themes added, active theme NOT changed
|
|
160
|
+
- Both: conflict resolution works correctly
|
|
161
|
+
|
|
162
|
+
## User Impact
|
|
163
|
+
|
|
164
|
+
**Zero breaking changes** - CLI behavior remains identical from user perspective.
|
|
165
|
+
|
|
166
|
+
## Code Reduction
|
|
167
|
+
|
|
168
|
+
| File | Before | After |
|
|
169
|
+
|------|--------|-------|
|
|
170
|
+
| create-project.js | ~80 lines | ~10 lines |
|
|
171
|
+
| add-themes-cli.js | ~120 lines | ~10 lines |
|
|
172
|
+
| **Total duplication** | ~30 lines | 0 lines |
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# Theme Addition Refactoring Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Refactor theme addition code to eliminate duplication by centralizing logic in AddThemesCommand class.
|
|
6
|
+
|
|
7
|
+
**Architecture:** AddThemesCommand becomes single source of truth for theme selection, conflict resolution, and copying. CLI files become simple wrappers (~10 lines). create-project.js handles active theme selection; add-themes-cli.js does not.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node.js, inquirer for prompts, jest for testing
|
|
10
|
+
|
|
11
|
+
**Reference design:** `docs/plans/2026-02-26-theme-addition-refactoring-design.md`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Task 1: Add theme selection prompt to AddThemesCommand
|
|
16
|
+
|
|
17
|
+
**Files:**
|
|
18
|
+
- Modify: `lib/add-themes-command.js`
|
|
19
|
+
|
|
20
|
+
**Step 1: Read current AddThemesCommand implementation**
|
|
21
|
+
|
|
22
|
+
Read the file to understand current structure, especially:
|
|
23
|
+
- How `selectThemes` prompt is currently handled
|
|
24
|
+
- The `execute()` method signature
|
|
25
|
+
- How themes are returned
|
|
26
|
+
|
|
27
|
+
**Step 2: Modify `_promptThemes` method to use Prompts class**
|
|
28
|
+
|
|
29
|
+
Update the method to use `Prompts.promptThemes()` directly:
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
_promptThemes(availableThemes) {
|
|
33
|
+
if (this.options.themes && this.options.themes.length > 0) {
|
|
34
|
+
return this.options.themes;
|
|
35
|
+
}
|
|
36
|
+
return Prompts.promptThemes(availableThemes);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Step 3: Update constructor to remove custom selectThemes prompt option**
|
|
41
|
+
|
|
42
|
+
Remove `prompts.selectThemes` from the constructor options. Theme selection is now built-in.
|
|
43
|
+
|
|
44
|
+
**Step 4: Add Prompts import**
|
|
45
|
+
|
|
46
|
+
Add at top of file:
|
|
47
|
+
```javascript
|
|
48
|
+
const { Prompts } = require('./prompts');
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Step 5: Run tests to verify no regressions**
|
|
52
|
+
|
|
53
|
+
Run: `npm test -- tests/add-themes-command.test.js`
|
|
54
|
+
Expected: All existing tests pass
|
|
55
|
+
|
|
56
|
+
**Step 6: Commit**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
git add lib/add-themes-command.js
|
|
60
|
+
git commit -m "refactor: AddThemesCommand uses built-in theme selection prompt"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Task 2: Add conflict resolution prompt to AddThemesCommand
|
|
66
|
+
|
|
67
|
+
**Files:**
|
|
68
|
+
- Modify: `lib/add-themes-command.js`
|
|
69
|
+
|
|
70
|
+
**Step 1: Create `_resolveConflictsInteractive` method**
|
|
71
|
+
|
|
72
|
+
Add method to handle conflict resolution using Prompts class:
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
async _resolveConflictsInteractive(conflicts) {
|
|
76
|
+
const result = await Prompts.promptConflictResolution(
|
|
77
|
+
conflicts.map(c => ({ name: c }))
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (result === 'skip-all') return { overwrite: [] };
|
|
81
|
+
if (result === 'overwrite-all') return { overwrite: conflicts };
|
|
82
|
+
if (result === 'cancel') return { overwrite: [] };
|
|
83
|
+
|
|
84
|
+
// Handle 'choose-each' or individual conflicts
|
|
85
|
+
const overwrite = [];
|
|
86
|
+
for (const conflict of conflicts) {
|
|
87
|
+
const choice = await Prompts.promptSingleConflict(conflict);
|
|
88
|
+
if (choice === 'overwrite') {
|
|
89
|
+
overwrite.push(conflict);
|
|
90
|
+
} else if (choice === 'cancel') {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { overwrite };
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Step 2: Update `_resolveConflicts` to use built-in prompt**
|
|
99
|
+
|
|
100
|
+
Modify to call `_resolveConflictsInteractive` when no custom prompt provided:
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
async _resolveConflicts(conflicts) {
|
|
104
|
+
if (this.options.prompts?.resolveConflicts) {
|
|
105
|
+
return this.options.prompts.resolveConflicts(conflicts);
|
|
106
|
+
}
|
|
107
|
+
return this._resolveConflictsInteractive(conflicts);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Step 3: Update constructor default prompts**
|
|
112
|
+
|
|
113
|
+
Remove requirement for `resolveConflicts` in prompts object - make it optional.
|
|
114
|
+
|
|
115
|
+
**Step 4: Run tests**
|
|
116
|
+
|
|
117
|
+
Run: `npm test -- tests/add-themes-command.test.js`
|
|
118
|
+
Expected: All existing tests pass
|
|
119
|
+
|
|
120
|
+
**Step 5: Commit**
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
git add lib/add-themes-command.js
|
|
124
|
+
git commit -m "refactor: AddThemesCommand uses built-in conflict resolution prompt"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Task 3: Ensure AddThemesCommand returns Theme objects
|
|
130
|
+
|
|
131
|
+
**Files:**
|
|
132
|
+
- Modify: `lib/add-themes-command.js`
|
|
133
|
+
- Test: `tests/add-themes-command.test.js`
|
|
134
|
+
|
|
135
|
+
**Step 1: Read execute() method return value**
|
|
136
|
+
|
|
137
|
+
Check what is currently returned - ensure `copied` array contains Theme objects with `name` property.
|
|
138
|
+
|
|
139
|
+
**Step 2: Verify Theme object structure**
|
|
140
|
+
|
|
141
|
+
Ensure copied themes have:
|
|
142
|
+
- `name` property
|
|
143
|
+
- Other necessary properties for downstream use
|
|
144
|
+
|
|
145
|
+
**Step 3: Add test for Theme object return**
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
test('execute returns Theme objects with name property', async () => {
|
|
149
|
+
const command = new AddThemesCommand({
|
|
150
|
+
templatePath: themesPath,
|
|
151
|
+
interactive: false
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const result = await command.execute(projectPath, {
|
|
155
|
+
themes: ['beam']
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
expect(result.copied).toHaveLength(1);
|
|
159
|
+
expect(result.copied[0]).toHaveProperty('name');
|
|
160
|
+
expect(result.copied[0].name).toBe('beam');
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Step 4: Run test to verify it passes**
|
|
165
|
+
|
|
166
|
+
Run: `npm test -- tests/add-themes-command.test.js -t "returns Theme objects"`
|
|
167
|
+
Expected: PASS
|
|
168
|
+
|
|
169
|
+
**Step 5: Commit**
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
git add lib/add-themes-command.js tests/add-themes-command.test.js
|
|
173
|
+
git commit -m "test: verify AddThemesCommand returns Theme objects"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Task 4: Ensure AddThemesCommand always checks conflicts
|
|
179
|
+
|
|
180
|
+
**Files:**
|
|
181
|
+
- Modify: `lib/add-themes-command.js`
|
|
182
|
+
|
|
183
|
+
**Step 1: Find _findConflicts usage**
|
|
184
|
+
|
|
185
|
+
Check where conflict checking happens in execute() method.
|
|
186
|
+
|
|
187
|
+
**Step 2: Ensure conflict check always runs**
|
|
188
|
+
|
|
189
|
+
Remove any conditional that skips conflict checking. The method should always run:
|
|
190
|
+
- In new projects: finds nothing (harmless)
|
|
191
|
+
- In existing projects: finds actual conflicts
|
|
192
|
+
|
|
193
|
+
**Step 3: Add test for conflict check in empty project**
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
test('execute checks conflicts even in new projects', async () => {
|
|
197
|
+
const command = new AddThemesCommand({
|
|
198
|
+
templatePath: themesPath,
|
|
199
|
+
interactive: false
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Create empty project (no existing themes)
|
|
203
|
+
const emptyProject = await createTempProject();
|
|
204
|
+
|
|
205
|
+
const result = await command.execute(emptyProject, {
|
|
206
|
+
themes: ['beam']
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Should succeed with no conflicts found
|
|
210
|
+
expect(result.conflicts).toEqual([]);
|
|
211
|
+
expect(result.copied).toHaveLength(1);
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Step 4: Run test**
|
|
216
|
+
|
|
217
|
+
Run: `npm test -- tests/add-themes-command.test.js -t "checks conflicts"`
|
|
218
|
+
Expected: PASS
|
|
219
|
+
|
|
220
|
+
**Step 5: Commit**
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
git add lib/add-themes-command.js tests/add-themes-command.test.js
|
|
224
|
+
git commit -m "refactor: AddThemesCommand always checks for conflicts"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Task 5: Simplify create-project.js theme addition
|
|
230
|
+
|
|
231
|
+
**Files:**
|
|
232
|
+
- Modify: `cli/commands/create-project.js`
|
|
233
|
+
- Test: `tests/cli.test.js`
|
|
234
|
+
|
|
235
|
+
**Step 1: Read current create-project.js theme code**
|
|
236
|
+
|
|
237
|
+
Locate `askAddThemes()` and `addThemesToProject()` functions.
|
|
238
|
+
|
|
239
|
+
**Step 2: Replace theme addition flow**
|
|
240
|
+
|
|
241
|
+
Replace entire theme addition section with:
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
// Add themes to project
|
|
245
|
+
const command = new AddThemesCommand({
|
|
246
|
+
templatePath: themesLibraryPath
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const { copied } = await command.execute(projectPath, {
|
|
250
|
+
skipConflictCheck: false
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Select active theme from copied themes
|
|
254
|
+
const themeNames = copied.map(t => t.name);
|
|
255
|
+
const activeTheme = await Prompts.promptActiveTheme(themeNames);
|
|
256
|
+
await ThemeManager.setActiveTheme(projectPath, activeTheme);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Step 3: Remove askAddThemes function**
|
|
260
|
+
|
|
261
|
+
Delete the `askAddThemes()` function - no longer needed.
|
|
262
|
+
|
|
263
|
+
**Step 4: Remove addThemesToProject function**
|
|
264
|
+
|
|
265
|
+
Delete the `addThemesToProject()` function - logic now in AddThemesCommand.
|
|
266
|
+
|
|
267
|
+
**Step 5: Update imports**
|
|
268
|
+
|
|
269
|
+
Ensure `Prompts` and `ThemeManager` are imported.
|
|
270
|
+
|
|
271
|
+
**Step 6: Run tests**
|
|
272
|
+
|
|
273
|
+
Run: `npm test -- tests/cli.test.js`
|
|
274
|
+
Expected: All tests pass
|
|
275
|
+
|
|
276
|
+
**Step 7: Manual test**
|
|
277
|
+
|
|
278
|
+
Run: `node index.js test-project --path /tmp`
|
|
279
|
+
Verify: Theme selection appears, active theme is prompted
|
|
280
|
+
|
|
281
|
+
**Step 8: Commit**
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
git add cli/commands/create-project.js
|
|
285
|
+
git commit -m "refactor: simplify create-project theme addition using AddThemesCommand"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Task 6: Simplify add-themes-cli.js
|
|
291
|
+
|
|
292
|
+
**Files:**
|
|
293
|
+
- Modify: `cli/commands/add-themes-cli.js`
|
|
294
|
+
- Test: `tests/cli.test.js`
|
|
295
|
+
|
|
296
|
+
**Step 1: Read current add-themes-cli.js**
|
|
297
|
+
|
|
298
|
+
Locate theme selection and active theme logic.
|
|
299
|
+
|
|
300
|
+
**Step 2: Replace theme addition flow**
|
|
301
|
+
|
|
302
|
+
Replace entire theme section with:
|
|
303
|
+
|
|
304
|
+
```javascript
|
|
305
|
+
const command = new AddThemesCommand({
|
|
306
|
+
templatePath: themesLibraryPath
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const { copied, skipped, conflicts } = await command.execute(projectPath, {
|
|
310
|
+
themes: themeNames || undefined // Use args if provided
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// Show summary
|
|
314
|
+
console.log(`\nCopied themes: ${copied.map(t => t.name).join(', ') || 'none'}`);
|
|
315
|
+
if (skipped.length) console.log(`Skipped: ${skipped.join(', ')}`);
|
|
316
|
+
if (conflicts.length) console.log(`Conflicts: ${conflicts.join(', ')}`);
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Step 3: Remove active theme prompt**
|
|
320
|
+
|
|
321
|
+
Delete all code related to `promptActiveTheme` and `ThemeManager.setActiveTheme`.
|
|
322
|
+
|
|
323
|
+
**Step 4: Remove VSCode settings update**
|
|
324
|
+
|
|
325
|
+
Delete VSCode settings code - now handled by AddThemesCommand.
|
|
326
|
+
|
|
327
|
+
**Step 5: Run tests**
|
|
328
|
+
|
|
329
|
+
Run: `npm test -- tests/cli.test.js`
|
|
330
|
+
Expected: All tests pass
|
|
331
|
+
|
|
332
|
+
**Step 6: Manual test**
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
cd /tmp/existing-project
|
|
336
|
+
node /stg/git/marp-presentation-template/index.js add-themes beam
|
|
337
|
+
```
|
|
338
|
+
Verify: Themes added, active theme NOT changed
|
|
339
|
+
|
|
340
|
+
**Step 7: Commit**
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
git add cli/commands/add-themes-cli.js
|
|
344
|
+
git commit -m "refactor: simplify add-themes-cli using AddThemesCommand, remove active theme logic"
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Task 7: Update integration tests
|
|
350
|
+
|
|
351
|
+
**Files:**
|
|
352
|
+
- Modify: `tests/cli.test.js`
|
|
353
|
+
|
|
354
|
+
**Step 1: Review existing CLI tests**
|
|
355
|
+
|
|
356
|
+
Check which tests are affected by the refactoring.
|
|
357
|
+
|
|
358
|
+
**Step 2: Update test expectations**
|
|
359
|
+
|
|
360
|
+
Ensure tests expect:
|
|
361
|
+
- Theme selection to be prompted
|
|
362
|
+
- Active theme to be set in create-project
|
|
363
|
+
- Active theme NOT to change in add-themes-cli
|
|
364
|
+
|
|
365
|
+
**Step 3: Add test for active theme preservation**
|
|
366
|
+
|
|
367
|
+
```javascript
|
|
368
|
+
test('add-themes command does not change active theme', async () => {
|
|
369
|
+
const project = await createProjectWithThemes(['beam']);
|
|
370
|
+
await ThemeManager.setActiveTheme(project.path, 'beam');
|
|
371
|
+
|
|
372
|
+
// Add more themes
|
|
373
|
+
await addThemesToProject(project.path, ['gaia-dark']);
|
|
374
|
+
|
|
375
|
+
const active = await ThemeManager.getActiveTheme(project.path);
|
|
376
|
+
expect(active).toBe('beam'); // Still beam, not changed
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**Step 4: Run all tests**
|
|
381
|
+
|
|
382
|
+
Run: `npm test`
|
|
383
|
+
Expected: All 175+ tests pass
|
|
384
|
+
|
|
385
|
+
**Step 5: Commit**
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
git add tests/cli.test.js
|
|
389
|
+
git commit -m "test: update CLI tests for refactored theme addition"
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Task 8: Final verification and documentation
|
|
395
|
+
|
|
396
|
+
**Files:**
|
|
397
|
+
- Modify: `CLAUDE.md` (if needed)
|
|
398
|
+
|
|
399
|
+
**Step 1: Run full test suite**
|
|
400
|
+
|
|
401
|
+
Run: `npm test`
|
|
402
|
+
Expected: 100% pass rate
|
|
403
|
+
|
|
404
|
+
**Step 2: Manual integration test**
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
# Test new project creation
|
|
408
|
+
node index.js test-new --path /tmp
|
|
409
|
+
cd /tmp/test-new
|
|
410
|
+
cat .vscode/settings.json # Verify themes listed
|
|
411
|
+
grep "marp.themeSet" marp.config.js # Verify active theme
|
|
412
|
+
|
|
413
|
+
# Test adding themes to existing project
|
|
414
|
+
node /stg/git/marp-presentation-template/index.js add-themes uncover-minimal
|
|
415
|
+
cat .vscode/settings.json # Verify new theme added
|
|
416
|
+
grep "marp.themeSet" marp.config.js # Verify active theme unchanged
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Step 3: Update CLAUDE.md if needed**
|
|
420
|
+
|
|
421
|
+
Document any API changes to AddThemesCommand.
|
|
422
|
+
|
|
423
|
+
**Step 4: Final commit**
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
git add CLAUDE.md
|
|
427
|
+
git commit -m "docs: update AddThemesCommand API documentation"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Step 5: Create summary PR commit**
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
git commit --allow-empty -m "refactor: complete theme addition refactoring
|
|
434
|
+
|
|
435
|
+
- AddThemesCommand now handles all theme addition logic
|
|
436
|
+
- create-project.js simplified from ~80 to ~10 lines
|
|
437
|
+
- add-themes-cli.js simplified from ~120 to ~10 lines
|
|
438
|
+
- Zero code duplication in theme addition
|
|
439
|
+
- Active theme selection only in create-project.js
|
|
440
|
+
- Conflict resolution always runs (harmless in new projects)
|
|
441
|
+
"
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## Verification Checklist
|
|
447
|
+
|
|
448
|
+
After completing all tasks:
|
|
449
|
+
|
|
450
|
+
- [ ] All unit tests pass (`npm test`)
|
|
451
|
+
- [ ] All integration tests pass
|
|
452
|
+
- [ ] Manual test: new project creation works with theme selection
|
|
453
|
+
- [ ] Manual test: add-themes adds themes without changing active theme
|
|
454
|
+
- [ ] VSCode settings updated correctly
|
|
455
|
+
- [ ] No duplicate code in CLI files
|
|
456
|
+
- [ ] Code review shows clean, maintainable structure
|