coursecode 0.1.24 → 0.1.26
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/framework/docs/FRAMEWORK_GUIDE.md +4 -0
- package/lib/mcp-prompts.js +12 -7
- package/lib/mcp-server.js +42 -0
- package/package.json +1 -1
|
@@ -662,6 +662,10 @@ Runs **in Node.js** during build (via `vite.framework-dev.config.js` `closeBundl
|
|
|
662
662
|
|
|
663
663
|
**Errors fail the build; warnings print but don't block.**
|
|
664
664
|
|
|
665
|
+
### MCP `coursecode_lint` — Unified Results
|
|
666
|
+
|
|
667
|
+
The MCP `coursecode_lint` tool always runs the build linter. When the preview server is running and the headless browser is connected, it also merges runtime errors from the preview server's error log into the same response. These are the same errors shown in the debug panel's Errors tab and returned by `coursecode_state` — LMS API misuse, console errors, uncaught exceptions, and data limit warnings. Runtime-sourced items are tagged with `source: 'runtime'` and `rule: 'runtime-error'`. The `runtimeLintIncluded` flag in the response indicates whether runtime errors were included. This gives AI agents a single tool for both static lint and runtime errors without needing a separate `coursecode_state` call.
|
|
668
|
+
|
|
665
669
|
### Shared Rules (`lib/validation-rules.js`)
|
|
666
670
|
|
|
667
671
|
Pure validation functions used by **both** linters. No environment-specific code (no DOM, no `fs`). Includes assessment validation, engagement validation, and result formatting.
|
package/lib/mcp-prompts.js
CHANGED
|
@@ -306,14 +306,17 @@ Use to discover available interactions before creating assessments.`,
|
|
|
306
306
|
|
|
307
307
|
{
|
|
308
308
|
name: 'coursecode_lint',
|
|
309
|
-
description: `Run the
|
|
309
|
+
description: `Run the course linter and get structured results.
|
|
310
|
+
|
|
311
|
+
Always runs build-time lint (config, CSS classes, structure). When the preview server is running and the headless browser is connected, also includes runtime errors from the preview server (same errors shown in coursecode_state and the debug panel Errors tab).
|
|
310
312
|
|
|
311
313
|
Returns:
|
|
312
|
-
- errors: [{slideId
|
|
313
|
-
- warnings: [{slideId
|
|
314
|
+
- errors: [{slideId?, rule, message, severity, source?, hint?}]
|
|
315
|
+
- warnings: [{slideId?, rule, message, severity, source?, class?, suggestion?, hint?}]
|
|
314
316
|
- passed: boolean
|
|
317
|
+
- runtimeLintIncluded: boolean (true when runtime errors were included)
|
|
315
318
|
|
|
316
|
-
|
|
319
|
+
Build-time rules (always checked):
|
|
317
320
|
- undefined-css-class: hallucinated or stale class names (with fix suggestions)
|
|
318
321
|
- unknown-component: unregistered data-component types
|
|
319
322
|
- requirement-missing-component: engagement requirement without matching component
|
|
@@ -322,9 +325,11 @@ Rules detected:
|
|
|
322
325
|
- assessment-id-mismatch: config ID doesn't match assessment ID
|
|
323
326
|
- invalid-gating: bad gating condition configuration
|
|
324
327
|
|
|
325
|
-
|
|
326
|
-
-
|
|
327
|
-
-
|
|
328
|
+
Runtime errors (included when preview is running, source='runtime'):
|
|
329
|
+
- LMS API misuse (GetValue before Initialize, SetValue after Terminate, etc.)
|
|
330
|
+
- Console errors and warnings from the course
|
|
331
|
+
- Uncaught exceptions and unhandled promise rejections
|
|
332
|
+
- Suspend data size warnings
|
|
328
333
|
|
|
329
334
|
Suppression: Add data-lint-ignore to any HTML element to suppress warnings for it and children.
|
|
330
335
|
data-lint-ignore — suppress all warnings
|
package/lib/mcp-server.js
CHANGED
|
@@ -247,6 +247,48 @@ export async function startMcpServer(options = {}) {
|
|
|
247
247
|
break;
|
|
248
248
|
case 'coursecode_lint':
|
|
249
249
|
result = await lintCourse();
|
|
250
|
+
// Merge runtime errors if headless browser is already connected
|
|
251
|
+
if (headless.isRunning()) {
|
|
252
|
+
try {
|
|
253
|
+
const runtimeErrors = await headless.evaluateParent(() => {
|
|
254
|
+
return window._stubPlayerState?.errorLog || [];
|
|
255
|
+
});
|
|
256
|
+
result.runtimeLintIncluded = true;
|
|
257
|
+
if (runtimeErrors.length > 0) {
|
|
258
|
+
const runtimeWarnings = runtimeErrors.filter(e => e.isWarning);
|
|
259
|
+
const runtimeErrs = runtimeErrors.filter(e => !e.isWarning);
|
|
260
|
+
if (runtimeWarnings.length > 0) {
|
|
261
|
+
result.warnings = (result.warnings || []).concat(
|
|
262
|
+
runtimeWarnings.map(e => ({
|
|
263
|
+
severity: 'warning',
|
|
264
|
+
type: e.type,
|
|
265
|
+
message: e.message,
|
|
266
|
+
hint: e.hint,
|
|
267
|
+
rule: 'runtime-error',
|
|
268
|
+
source: 'runtime'
|
|
269
|
+
}))
|
|
270
|
+
);
|
|
271
|
+
result.warningCount = result.warnings.length;
|
|
272
|
+
}
|
|
273
|
+
if (runtimeErrs.length > 0) {
|
|
274
|
+
result.errors = (result.errors || []).concat(
|
|
275
|
+
runtimeErrs.map(e => ({
|
|
276
|
+
severity: 'error',
|
|
277
|
+
type: e.type,
|
|
278
|
+
message: e.message,
|
|
279
|
+
hint: e.hint,
|
|
280
|
+
rule: 'runtime-error',
|
|
281
|
+
source: 'runtime'
|
|
282
|
+
}))
|
|
283
|
+
);
|
|
284
|
+
result.errorCount = result.errors.length;
|
|
285
|
+
result.passed = result.errors.length === 0;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
} catch {
|
|
289
|
+
// Headless browser may have disconnected — non-fatal, build lint still valid
|
|
290
|
+
}
|
|
291
|
+
}
|
|
250
292
|
break;
|
|
251
293
|
|
|
252
294
|
case 'coursecode_export_content':
|