coursecode 0.1.29 → 0.1.32
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.
|
@@ -47,6 +47,20 @@
|
|
|
47
47
|
height: 100%; /* Fill the entire grid cell height (for equal row heights) */
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/* When multiple flip cards sit side-by-side in any grid or flex container,
|
|
51
|
+
align back-face content to the top so headings line up across cards.
|
|
52
|
+
:has(> .flip-card ~ .flip-card) matches any parent containing 2+ flip cards. */
|
|
53
|
+
:has(> .flip-card ~ .flip-card) > .flip-card .flip-card-back {
|
|
54
|
+
justify-content: flex-start;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Back-face content stretches to fill the card and uses space-between
|
|
58
|
+
so the heading sits at top and remaining content anchors to bottom */
|
|
59
|
+
:has(> .flip-card ~ .flip-card) > .flip-card .flip-card-back .flip-card-content {
|
|
60
|
+
flex: 1;
|
|
61
|
+
justify-content: space-between;
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
.flip-card-inner {
|
|
51
65
|
display: grid; /* Grid allows both faces to contribute to height */
|
|
52
66
|
width: 100%;
|
|
@@ -664,7 +664,7 @@ Runs **in Node.js** during build (via `vite.framework-dev.config.js` `closeBundl
|
|
|
664
664
|
|
|
665
665
|
### MCP `coursecode_lint` — Build-Time Only
|
|
666
666
|
|
|
667
|
-
The MCP `coursecode_lint` tool runs the build linter (config validation, CSS class verification, structure checks). It does NOT include runtime errors. For runtime errors
|
|
667
|
+
The MCP `coursecode_lint` tool runs the build linter (config validation, CSS class verification, structure checks). It does NOT include runtime errors. For runtime errors and contrast warnings, use `coursecode_errors` (lightweight — just errors and console logs) or `coursecode_state` (full state snapshot including errors).
|
|
668
668
|
|
|
669
669
|
### Shared Rules (`lib/validation-rules.js`)
|
|
670
670
|
|
|
@@ -873,6 +873,7 @@ If the preview is not running, runtime tools fail fast with a clear error messag
|
|
|
873
873
|
| Tool | Purpose | Returns |
|
|
874
874
|
|------|---------|--------|
|
|
875
875
|
| `coursecode_state` | Full course snapshot | `{slide, toc, interactions, engagement, lmsState, apiLog, errors, frameworkLogs, consoleLogs}` |
|
|
876
|
+
| `coursecode_errors` | Errors + console logs only | `{errors, consoleLogs, count, clean}` — same error sources as `coursecode_state`, without the state payload |
|
|
876
877
|
| `coursecode_navigate` | Go to slide by ID | `{slide, interactions, engagement, accessibility}` |
|
|
877
878
|
| `coursecode_interact` | Set response + evaluate | `{interactionId, response}` → `{correct, score, feedback}` |
|
|
878
879
|
| `coursecode_screenshot` | Visual capture (JPEG) | Optional `slideId` to navigate first, `fullPage` for scroll capture |
|
|
@@ -302,7 +302,7 @@ Once connected, your AI assistant gains these capabilities:
|
|
|
302
302
|
| `coursecode_interaction_catalog` | Browse available interaction types (multiple choice, drag-drop, etc.) |
|
|
303
303
|
| `coursecode_css_catalog` | Browse available CSS classes by category |
|
|
304
304
|
| `coursecode_icon_catalog` | Browse available icons by name/category |
|
|
305
|
-
|
|
305
|
+
|
|
306
306
|
| `coursecode_workflow_status` | Get guidance on what to do next based on your project's current state |
|
|
307
307
|
| `coursecode_build` | Build the course for LMS deployment |
|
|
308
308
|
|
package/lib/mcp-prompts.js
CHANGED
|
@@ -34,6 +34,29 @@ Returns:
|
|
|
34
34
|
- consoleLogs: browser console warnings/errors [{type, text, time}]
|
|
35
35
|
|
|
36
36
|
Use this first to understand the course state before taking actions.
|
|
37
|
+
For error checking only (after file edits), prefer coursecode_errors — same error sources, smaller payload.
|
|
38
|
+
Requires preview server to be running.`,
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {},
|
|
42
|
+
required: []
|
|
43
|
+
},
|
|
44
|
+
annotations: {
|
|
45
|
+
readOnlyHint: true,
|
|
46
|
+
idempotentHint: true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'coursecode_errors',
|
|
51
|
+
description: `Get runtime errors and warnings from the live preview. Uses the same error sources as coursecode_state (preview server errors + browser console) but without the heavyweight state payload.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
- errors: [{type, message, hint?, isWarning?}] — preview server errors and warnings
|
|
55
|
+
- consoleLogs: [{type, text, time}] — browser console warnings/errors
|
|
56
|
+
- count: total number of errors + console logs
|
|
57
|
+
- clean: true if no errors, warnings, or console issues
|
|
58
|
+
|
|
59
|
+
Use after making file changes to check for breakage without the overhead of coursecode_state.
|
|
37
60
|
Requires preview server to be running.`,
|
|
38
61
|
inputSchema: {
|
|
39
62
|
type: 'object',
|
|
@@ -406,68 +429,7 @@ Use to discover available icons before authoring slides or configuring menus.`,
|
|
|
406
429
|
readOnlyHint: true,
|
|
407
430
|
idempotentHint: true
|
|
408
431
|
}
|
|
409
|
-
},
|
|
410
|
-
{
|
|
411
|
-
name: 'coursecode_export_content',
|
|
412
|
-
description: `Extract course content as structured Markdown or JSON for review.
|
|
413
|
-
|
|
414
|
-
Returns the full text content of the course: slide headers, body text, tabs, accordions, callouts, cards, interactions, assessment questions, narration, config, and structure overview.
|
|
415
432
|
|
|
416
|
-
Use cases:
|
|
417
|
-
- Compare built course against COURSE_OUTLINE.md for accuracy
|
|
418
|
-
- Review all interactions and assessment questions at once
|
|
419
|
-
- Audit content wording and consistency across slides
|
|
420
|
-
- Generate content for localization or SME review
|
|
421
|
-
|
|
422
|
-
Filtering options keep output manageable:
|
|
423
|
-
- slides: scope to specific slide IDs
|
|
424
|
-
- interactionsOnly: just Q&A, no slide content
|
|
425
|
-
- excludeInteractions: content only, no Q&A
|
|
426
|
-
- format: 'md' (default) or 'json' for structured data
|
|
427
|
-
|
|
428
|
-
For large courses (>40KB), full exports automatically return a summary with per-slide sizes instead. Use the slides parameter to export specific content.
|
|
429
|
-
|
|
430
|
-
Does not require preview server.`,
|
|
431
|
-
inputSchema: {
|
|
432
|
-
type: 'object',
|
|
433
|
-
properties: {
|
|
434
|
-
slides: {
|
|
435
|
-
type: 'string',
|
|
436
|
-
description: 'Comma-separated slide IDs to export (default: all slides)'
|
|
437
|
-
},
|
|
438
|
-
interactionsOnly: {
|
|
439
|
-
type: 'boolean',
|
|
440
|
-
description: 'Export only interactions and assessment questions (no slide content)'
|
|
441
|
-
},
|
|
442
|
-
includeNarration: {
|
|
443
|
-
type: 'boolean',
|
|
444
|
-
description: 'Include narration transcripts (default: false)'
|
|
445
|
-
},
|
|
446
|
-
includeAnswers: {
|
|
447
|
-
type: 'boolean',
|
|
448
|
-
description: 'Include correct answers for interactions (default: true)'
|
|
449
|
-
},
|
|
450
|
-
includeFeedback: {
|
|
451
|
-
type: 'boolean',
|
|
452
|
-
description: 'Include feedback text (default: true)'
|
|
453
|
-
},
|
|
454
|
-
excludeInteractions: {
|
|
455
|
-
type: 'boolean',
|
|
456
|
-
description: 'Exclude all interactions from output (default: false)'
|
|
457
|
-
},
|
|
458
|
-
format: {
|
|
459
|
-
type: 'string',
|
|
460
|
-
description: 'Output format: md or json (default: md)',
|
|
461
|
-
enum: ['md', 'json']
|
|
462
|
-
}
|
|
463
|
-
},
|
|
464
|
-
required: []
|
|
465
|
-
},
|
|
466
|
-
annotations: {
|
|
467
|
-
readOnlyHint: true,
|
|
468
|
-
idempotentHint: true
|
|
469
|
-
}
|
|
470
|
-
},
|
|
471
433
|
];
|
|
472
434
|
|
|
473
435
|
// ========================================
|
|
@@ -692,7 +654,6 @@ Visually verify and polish the course using the preview server.
|
|
|
692
654
|
- coursecode_navigate — go to any slide by ID (get IDs from coursecode_state)
|
|
693
655
|
- coursecode_screenshot — capture visual state (accepts slideId to navigate+capture in one call)
|
|
694
656
|
- coursecode_interact — test interactions with responses
|
|
695
|
-
- coursecode_export_content — extract all text content to review or compare against outline
|
|
696
657
|
- coursecode_lint — validate after file changes
|
|
697
658
|
|
|
698
659
|
4. Efficient iteration loop:
|
package/lib/mcp-server.js
CHANGED
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
lintCourse,
|
|
31
31
|
buildCourse
|
|
32
32
|
} from './authoring-api.js';
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
import headless from './headless-browser.js';
|
|
35
35
|
import { TOOLS, buildInstructions, getWorkflowStatusWithInstructions } from './mcp-prompts.js';
|
|
36
36
|
|
|
@@ -231,6 +231,30 @@ export async function startMcpServer(options = {}) {
|
|
|
231
231
|
}
|
|
232
232
|
break;
|
|
233
233
|
|
|
234
|
+
case 'coursecode_errors': {
|
|
235
|
+
// Same error-gathering mechanism as coursecode_state,
|
|
236
|
+
// but without the heavyweight state payload (TOC, interactions, etc.)
|
|
237
|
+
await ensureHeadless(port);
|
|
238
|
+
let errors = [];
|
|
239
|
+
try {
|
|
240
|
+
const errResp = await fetch(`http://localhost:${port}/__lms/errors`);
|
|
241
|
+
if (errResp.ok) {
|
|
242
|
+
const errData = await errResp.json();
|
|
243
|
+
errors = [...(errData.errors || []), ...(errData.warnings || [])];
|
|
244
|
+
}
|
|
245
|
+
} catch {
|
|
246
|
+
// Preview server unreachable — errors array stays empty
|
|
247
|
+
}
|
|
248
|
+
const consoleLogs = headless.getConsoleLogs();
|
|
249
|
+
result = {
|
|
250
|
+
errors,
|
|
251
|
+
consoleLogs,
|
|
252
|
+
count: errors.length + consoleLogs.length,
|
|
253
|
+
clean: errors.length === 0 && consoleLogs.length === 0
|
|
254
|
+
};
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
|
|
234
258
|
// === Workflow & build tools ===
|
|
235
259
|
case 'coursecode_workflow_status':
|
|
236
260
|
result = await getWorkflowStatusWithInstructions(port);
|
|
@@ -258,17 +282,7 @@ export async function startMcpServer(options = {}) {
|
|
|
258
282
|
result = await lintCourse();
|
|
259
283
|
break;
|
|
260
284
|
|
|
261
|
-
|
|
262
|
-
result = await getContentExport(args || {});
|
|
263
|
-
if (result === null) {
|
|
264
|
-
throw new Error('Failed to export content. Ensure course-config.js exists in course/');
|
|
265
|
-
}
|
|
266
|
-
return {
|
|
267
|
-
content: [{
|
|
268
|
-
type: 'text',
|
|
269
|
-
text: result
|
|
270
|
-
}]
|
|
271
|
-
};
|
|
285
|
+
|
|
272
286
|
|
|
273
287
|
default:
|
|
274
288
|
throw new Error(`Unknown tool: ${name}`);
|
|
@@ -129,6 +129,16 @@ export function createEditModeHandlers(context) {
|
|
|
129
129
|
outline-offset: 2px;
|
|
130
130
|
background-color: rgba(245, 158, 11, 0.08);
|
|
131
131
|
}
|
|
132
|
+
.edit-mode-active .flip-card,
|
|
133
|
+
.edit-mode-active .accordion-button,
|
|
134
|
+
.edit-mode-active [data-action="select-tab"],
|
|
135
|
+
.edit-mode-active [data-action="toggle-collapse"],
|
|
136
|
+
.edit-mode-active [data-component="modal-trigger"],
|
|
137
|
+
.edit-mode-active .timeline-event,
|
|
138
|
+
.edit-mode-active [data-component="lightbox"],
|
|
139
|
+
.edit-mode-active [data-action="toggle-dropdown"] {
|
|
140
|
+
pointer-events: none;
|
|
141
|
+
}
|
|
132
142
|
`;
|
|
133
143
|
doc.head.appendChild(styleEl);
|
|
134
144
|
}
|