@lessonkit/lxpack 1.5.0 → 1.7.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/dist/index.d.cts CHANGED
@@ -53,8 +53,31 @@ type FindMultipleHotspotsAssessmentDescriptor = {
53
53
  correctTargetIds: string[];
54
54
  passingScore?: number;
55
55
  };
56
+ type SortParagraphsAssessmentDescriptor = {
57
+ kind: "sortParagraphs";
58
+ checkId: CheckId;
59
+ question: string;
60
+ paragraphs: string[];
61
+ correctOrder: number[];
62
+ passingScore?: number;
63
+ };
64
+ type GuessTheAnswerAssessmentDescriptor = {
65
+ kind: "guessTheAnswer";
66
+ checkId: CheckId;
67
+ question: string;
68
+ answer: string;
69
+ passingScore?: number;
70
+ };
71
+ type MultimediaChoiceAssessmentDescriptor = {
72
+ kind: "multimediaChoice";
73
+ checkId: CheckId;
74
+ question: string;
75
+ choices: string[];
76
+ answer: string;
77
+ passingScore?: number;
78
+ };
56
79
  /** Discriminated assessment entries in lessonkit.json (defaults to MCQ when kind omitted). */
57
- type AssessmentDescriptor = McqAssessmentDescriptor | TrueFalseAssessmentDescriptor | FillInBlanksAssessmentDescriptor | FindHotspotAssessmentDescriptor | FindMultipleHotspotsAssessmentDescriptor;
80
+ type AssessmentDescriptor = McqAssessmentDescriptor | TrueFalseAssessmentDescriptor | FillInBlanksAssessmentDescriptor | FindHotspotAssessmentDescriptor | FindMultipleHotspotsAssessmentDescriptor | SortParagraphsAssessmentDescriptor | GuessTheAnswerAssessmentDescriptor | MultimediaChoiceAssessmentDescriptor;
58
81
  type LessonkitCourseDescriptor = {
59
82
  courseId: CourseId;
60
83
  title: string;
@@ -127,6 +150,8 @@ type ProjectPathsInput = {
127
150
  lxpackOutDir?: string;
128
151
  outputBaseDir?: string;
129
152
  };
153
+ /** Validate lessonkit.json `name` for safe default export/archive paths. */
154
+ declare function validateManifestName(name: string): string | null;
130
155
  /** Validate lessonkit.json paths.* entries stay under projectRoot. */
131
156
  declare function validateProjectPaths(projectRoot: string, paths: ProjectPathsInput): DescriptorValidationIssue[];
132
157
  /**
@@ -155,15 +180,30 @@ type SpaLessonEntry = {
155
180
  path: string;
156
181
  };
157
182
  declare function resolveSpaLessons(descriptor: LessonkitCourseDescriptor): SpaLessonEntry[];
183
+ /**
184
+ * Convert a `lessonkit.json` course descriptor to portable interchange JSON for `.lkcourse`.
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * import { descriptorToInterchange } from "@lessonkit/lxpack";
189
+ *
190
+ * const interchange = descriptorToInterchange(manifest.course);
191
+ * ```
192
+ */
158
193
  declare function descriptorToInterchange(descriptor: LessonkitCourseDescriptor): LessonkitInterchangeV1;
159
194
 
160
195
  type LxpackInjectedAssessment = {
161
196
  id: string;
162
197
  title?: string;
163
198
  passingScore: number;
199
+ maxAttempts?: number;
200
+ shuffleChoices?: boolean;
201
+ showFeedback?: "never" | "immediate" | "end";
164
202
  questions: Array<{
165
203
  id: string;
166
204
  prompt: string;
205
+ explanation?: string;
206
+ selectionMode?: "single" | "multiple";
167
207
  choices: Array<{
168
208
  id: string;
169
209
  text: string;
@@ -199,6 +239,18 @@ type WriteLxpackProjectResult = {
199
239
  };
200
240
  /**
201
241
  * Materialize an LXPack project tree from a LessonKit descriptor (delegates to LXPack 0.6+).
242
+ *
243
+ * @example
244
+ * ```ts
245
+ * import { writeLxpackProject } from "@lessonkit/lxpack";
246
+ *
247
+ * await writeLxpackProject({
248
+ * descriptor: courseFromLessonkitJson,
249
+ * outDir: ".lxpack/course",
250
+ * spaDistDir: "dist",
251
+ * projectRoot: process.cwd(),
252
+ * });
253
+ * ```
202
254
  */
203
255
  declare function writeLxpackProject(options: WriteLxpackProjectOptions): Promise<WriteLxpackProjectResult>;
204
256
 
@@ -225,6 +277,9 @@ type BuildStagingPackageResult = {
225
277
  }>;
226
278
  outputPath?: string;
227
279
  outputDir?: string;
280
+ /** Absolute project-root output path when `output` was explicitly requested. */
281
+ requestedOutputPath?: string;
282
+ requestedOutputDir?: string;
228
283
  } | {
229
284
  ok: false;
230
285
  stagingDir: string;
@@ -260,6 +315,8 @@ type PackageLessonkitCourseOptions = WriteLxpackProjectOptions & {
260
315
  outputBaseDir?: string;
261
316
  /** Treat React parity warnings as packaging errors. */
262
317
  strictParity?: boolean;
318
+ /** Treat LXPack build warnings as packaging errors. */
319
+ strictBuild?: boolean;
263
320
  };
264
321
  type PackageLessonkitCourseResult = {
265
322
  ok: true;
@@ -282,12 +339,43 @@ type PackageLessonkitCourseResult = {
282
339
  severity?: string;
283
340
  }>;
284
341
  };
342
+ /**
343
+ * Validate an on-disk LXPack course directory before packaging.
344
+ *
345
+ * @example
346
+ * ```ts
347
+ * import { validateLessonkitProject } from "@lessonkit/lxpack";
348
+ *
349
+ * const result = await validateLessonkitProject({
350
+ * courseDir: ".lxpack/course",
351
+ * target: "scorm12",
352
+ * });
353
+ * ```
354
+ */
285
355
  declare function validateLessonkitProject(options: ValidateLessonkitProjectOptions): Promise<ValidateCourseResult>;
286
356
  declare function buildLessonkitProject(options: BuildLessonkitProjectOptions): Promise<BuildCourseResult>;
287
357
 
288
358
  /**
289
359
  * Package a built SPA into SCORM, xAPI, cmi5, or standalone LMS artifacts.
290
360
  * Prefer `lessonkit package --target …` in course projects; call directly for custom pipelines.
361
+ *
362
+ * @example
363
+ * ```ts
364
+ * import { packageLessonkitCourse } from "@lessonkit/lxpack";
365
+ *
366
+ * const result = await packageLessonkitCourse({
367
+ * descriptor: manifest.course,
368
+ * outDir: ".lxpack/course",
369
+ * spaDistDir: "dist",
370
+ * projectRoot: process.cwd(),
371
+ * target: "scorm12",
372
+ * strictBuild: true,
373
+ * });
374
+ * if (!result.ok) console.error(result.issues);
375
+ * ```
376
+ *
377
+ * @remarks Returns `{ ok: false, issues }` (does not throw) for manifest parity failures,
378
+ * missing `dist/`, LXPack validation errors, or `strictBuild` / `strictParity` warnings.
291
379
  */
292
380
  declare function packageLessonkitCourse(options: PackageLessonkitCourseOptions): Promise<PackageLessonkitCourseResult>;
293
381
 
@@ -311,6 +399,11 @@ declare function validatePackageInputs(options: Pick<PackageLessonkitCourseOptio
311
399
  }): ValidatePackageInputsResult;
312
400
  declare function remapArtifactPaths(stagingRoot: string, outDir: string, artifactPath: string | undefined): string | undefined;
313
401
 
402
+ /**
403
+ * Reject symlinks and paths escaping dist roots before packaging LMS artifacts.
404
+ */
405
+ declare function assertSpaDistContentsSafe(spaDirs: Record<string, string>, projectRoot?: string): Promise<void>;
406
+
314
407
  type LessonkitManifestPaths = {
315
408
  spaDistDir: string;
316
409
  lxpackOutDir: string;
@@ -340,4 +433,121 @@ type ParseManifestResult = {
340
433
  declare function parseLessonkitManifest(raw: unknown, label?: string, projectRoot?: string): ParseManifestResult;
341
434
  declare function loadLessonkitManifestFromFile(readJson: () => Promise<unknown>, label?: string, projectRoot?: string): Promise<ParseManifestResult>;
342
435
 
343
- export { type AssessmentDescriptor, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type FillInBlanksAssessmentDescriptor, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, extractAssessments, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };
436
+ type LkcourseEnvelopeV1 = {
437
+ format: "lkcourse";
438
+ schemaVersion: 1;
439
+ lessonkitVersion: string;
440
+ exportedAt: string;
441
+ sourceManifest: LessonkitManifest;
442
+ entries: string[];
443
+ };
444
+ type BlockTreeNodeV1 = {
445
+ type: string;
446
+ rawTag?: string;
447
+ courseId?: string;
448
+ lessonId?: string;
449
+ checkId?: string;
450
+ blockId?: string;
451
+ nodeId?: string;
452
+ children?: BlockTreeNodeV1[];
453
+ };
454
+ type BlockTreeV1 = {
455
+ schemaVersion: 1;
456
+ sources: string[];
457
+ blocks: BlockTreeNodeV1[];
458
+ };
459
+ type LkcourseValidationIssue = {
460
+ path: string;
461
+ message: string;
462
+ };
463
+ type ExportLkcourseOptions = {
464
+ projectRoot: string;
465
+ manifest: LessonkitManifest;
466
+ outPath?: string;
467
+ includeBlockTree?: boolean;
468
+ lessonkitVersion?: string;
469
+ };
470
+ type ExportLkcourseResult = {
471
+ ok: true;
472
+ archivePath: string;
473
+ fileCount: number;
474
+ includeBlockTree: boolean;
475
+ } | {
476
+ ok: false;
477
+ issues: LkcourseValidationIssue[];
478
+ };
479
+ type ValidateLkcourseResult = {
480
+ ok: true;
481
+ envelope: LkcourseEnvelopeV1;
482
+ interchange: LessonkitInterchangeV1;
483
+ } | {
484
+ ok: false;
485
+ issues: LkcourseValidationIssue[];
486
+ };
487
+ type ImportLkcourseOptions = {
488
+ archivePath: string;
489
+ targetDir: string;
490
+ };
491
+ type ImportLkcourseResult = {
492
+ ok: true;
493
+ targetDir: string;
494
+ manifest: LessonkitManifest;
495
+ interchange: LessonkitInterchangeV1;
496
+ fileCount: number;
497
+ } | {
498
+ ok: false;
499
+ issues: LkcourseValidationIssue[];
500
+ };
501
+ type ExtractBlockTreeOptions = {
502
+ projectRoot: string;
503
+ blockTypes?: string[];
504
+ appSources?: string[];
505
+ };
506
+
507
+ type ParseEnvelopeResult = {
508
+ ok: true;
509
+ envelope: LkcourseEnvelopeV1;
510
+ } | {
511
+ ok: false;
512
+ issues: LkcourseValidationIssue[];
513
+ };
514
+ declare function parseLkcourseEnvelope(raw: unknown, label?: string): ParseEnvelopeResult;
515
+
516
+ declare function extractBlockTree(options: ExtractBlockTreeOptions): BlockTreeV1;
517
+
518
+ /**
519
+ * Build a portable `.lkcourse` zip (manifest envelope + interchange + dist).
520
+ * Prefer `lessonkit export` in course projects.
521
+ *
522
+ * @example
523
+ * ```ts
524
+ * import { exportLkcourse } from "@lessonkit/lxpack";
525
+ *
526
+ * const result = await exportLkcourse({
527
+ * projectRoot: "/path/to/course",
528
+ * manifest: parsedLessonkitJson,
529
+ * archivePath: "handoff.lkcourse",
530
+ * });
531
+ * ```
532
+ */
533
+ declare function exportLkcourse(options: ExportLkcourseOptions): Promise<ExportLkcourseResult>;
534
+
535
+ declare function validateLkcourseArchiveEntries(entries: Map<string, Uint8Array>, _archiveLabel: string): ValidateLkcourseResult;
536
+ declare function validateLkcourse(archivePath: string): ValidateLkcourseResult;
537
+
538
+ /**
539
+ * Extract a `.lkcourse` archive into a project directory (manifest + dist tree).
540
+ *
541
+ * @example
542
+ * ```ts
543
+ * import { importLkcourse } from "@lessonkit/lxpack";
544
+ *
545
+ * const result = await importLkcourse({
546
+ * archivePath: "handoff.lkcourse",
547
+ * targetDir: "/path/to/dest",
548
+ * });
549
+ * ```
550
+ */
551
+ declare function importLkcourse(options: ImportLkcourseOptions): Promise<ImportLkcourseResult>;
552
+
553
+ export { type AssessmentDescriptor, type BlockTreeNodeV1, type BlockTreeV1, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type ExportLkcourseOptions, type ExportLkcourseResult, type ExtractBlockTreeOptions, type FillInBlanksAssessmentDescriptor, type ImportLkcourseOptions, type ImportLkcourseResult, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LkcourseEnvelopeV1, type LkcourseValidationIssue, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidateLkcourseResult, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assertSpaDistContentsSafe, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, exportLkcourse, extractAssessments, extractBlockTree, importLkcourse, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, parseLkcourseEnvelope, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validateLkcourse, validateLkcourseArchiveEntries, validateManifestName, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };
package/dist/index.d.ts CHANGED
@@ -53,8 +53,31 @@ type FindMultipleHotspotsAssessmentDescriptor = {
53
53
  correctTargetIds: string[];
54
54
  passingScore?: number;
55
55
  };
56
+ type SortParagraphsAssessmentDescriptor = {
57
+ kind: "sortParagraphs";
58
+ checkId: CheckId;
59
+ question: string;
60
+ paragraphs: string[];
61
+ correctOrder: number[];
62
+ passingScore?: number;
63
+ };
64
+ type GuessTheAnswerAssessmentDescriptor = {
65
+ kind: "guessTheAnswer";
66
+ checkId: CheckId;
67
+ question: string;
68
+ answer: string;
69
+ passingScore?: number;
70
+ };
71
+ type MultimediaChoiceAssessmentDescriptor = {
72
+ kind: "multimediaChoice";
73
+ checkId: CheckId;
74
+ question: string;
75
+ choices: string[];
76
+ answer: string;
77
+ passingScore?: number;
78
+ };
56
79
  /** Discriminated assessment entries in lessonkit.json (defaults to MCQ when kind omitted). */
57
- type AssessmentDescriptor = McqAssessmentDescriptor | TrueFalseAssessmentDescriptor | FillInBlanksAssessmentDescriptor | FindHotspotAssessmentDescriptor | FindMultipleHotspotsAssessmentDescriptor;
80
+ type AssessmentDescriptor = McqAssessmentDescriptor | TrueFalseAssessmentDescriptor | FillInBlanksAssessmentDescriptor | FindHotspotAssessmentDescriptor | FindMultipleHotspotsAssessmentDescriptor | SortParagraphsAssessmentDescriptor | GuessTheAnswerAssessmentDescriptor | MultimediaChoiceAssessmentDescriptor;
58
81
  type LessonkitCourseDescriptor = {
59
82
  courseId: CourseId;
60
83
  title: string;
@@ -127,6 +150,8 @@ type ProjectPathsInput = {
127
150
  lxpackOutDir?: string;
128
151
  outputBaseDir?: string;
129
152
  };
153
+ /** Validate lessonkit.json `name` for safe default export/archive paths. */
154
+ declare function validateManifestName(name: string): string | null;
130
155
  /** Validate lessonkit.json paths.* entries stay under projectRoot. */
131
156
  declare function validateProjectPaths(projectRoot: string, paths: ProjectPathsInput): DescriptorValidationIssue[];
132
157
  /**
@@ -155,15 +180,30 @@ type SpaLessonEntry = {
155
180
  path: string;
156
181
  };
157
182
  declare function resolveSpaLessons(descriptor: LessonkitCourseDescriptor): SpaLessonEntry[];
183
+ /**
184
+ * Convert a `lessonkit.json` course descriptor to portable interchange JSON for `.lkcourse`.
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * import { descriptorToInterchange } from "@lessonkit/lxpack";
189
+ *
190
+ * const interchange = descriptorToInterchange(manifest.course);
191
+ * ```
192
+ */
158
193
  declare function descriptorToInterchange(descriptor: LessonkitCourseDescriptor): LessonkitInterchangeV1;
159
194
 
160
195
  type LxpackInjectedAssessment = {
161
196
  id: string;
162
197
  title?: string;
163
198
  passingScore: number;
199
+ maxAttempts?: number;
200
+ shuffleChoices?: boolean;
201
+ showFeedback?: "never" | "immediate" | "end";
164
202
  questions: Array<{
165
203
  id: string;
166
204
  prompt: string;
205
+ explanation?: string;
206
+ selectionMode?: "single" | "multiple";
167
207
  choices: Array<{
168
208
  id: string;
169
209
  text: string;
@@ -199,6 +239,18 @@ type WriteLxpackProjectResult = {
199
239
  };
200
240
  /**
201
241
  * Materialize an LXPack project tree from a LessonKit descriptor (delegates to LXPack 0.6+).
242
+ *
243
+ * @example
244
+ * ```ts
245
+ * import { writeLxpackProject } from "@lessonkit/lxpack";
246
+ *
247
+ * await writeLxpackProject({
248
+ * descriptor: courseFromLessonkitJson,
249
+ * outDir: ".lxpack/course",
250
+ * spaDistDir: "dist",
251
+ * projectRoot: process.cwd(),
252
+ * });
253
+ * ```
202
254
  */
203
255
  declare function writeLxpackProject(options: WriteLxpackProjectOptions): Promise<WriteLxpackProjectResult>;
204
256
 
@@ -225,6 +277,9 @@ type BuildStagingPackageResult = {
225
277
  }>;
226
278
  outputPath?: string;
227
279
  outputDir?: string;
280
+ /** Absolute project-root output path when `output` was explicitly requested. */
281
+ requestedOutputPath?: string;
282
+ requestedOutputDir?: string;
228
283
  } | {
229
284
  ok: false;
230
285
  stagingDir: string;
@@ -260,6 +315,8 @@ type PackageLessonkitCourseOptions = WriteLxpackProjectOptions & {
260
315
  outputBaseDir?: string;
261
316
  /** Treat React parity warnings as packaging errors. */
262
317
  strictParity?: boolean;
318
+ /** Treat LXPack build warnings as packaging errors. */
319
+ strictBuild?: boolean;
263
320
  };
264
321
  type PackageLessonkitCourseResult = {
265
322
  ok: true;
@@ -282,12 +339,43 @@ type PackageLessonkitCourseResult = {
282
339
  severity?: string;
283
340
  }>;
284
341
  };
342
+ /**
343
+ * Validate an on-disk LXPack course directory before packaging.
344
+ *
345
+ * @example
346
+ * ```ts
347
+ * import { validateLessonkitProject } from "@lessonkit/lxpack";
348
+ *
349
+ * const result = await validateLessonkitProject({
350
+ * courseDir: ".lxpack/course",
351
+ * target: "scorm12",
352
+ * });
353
+ * ```
354
+ */
285
355
  declare function validateLessonkitProject(options: ValidateLessonkitProjectOptions): Promise<ValidateCourseResult>;
286
356
  declare function buildLessonkitProject(options: BuildLessonkitProjectOptions): Promise<BuildCourseResult>;
287
357
 
288
358
  /**
289
359
  * Package a built SPA into SCORM, xAPI, cmi5, or standalone LMS artifacts.
290
360
  * Prefer `lessonkit package --target …` in course projects; call directly for custom pipelines.
361
+ *
362
+ * @example
363
+ * ```ts
364
+ * import { packageLessonkitCourse } from "@lessonkit/lxpack";
365
+ *
366
+ * const result = await packageLessonkitCourse({
367
+ * descriptor: manifest.course,
368
+ * outDir: ".lxpack/course",
369
+ * spaDistDir: "dist",
370
+ * projectRoot: process.cwd(),
371
+ * target: "scorm12",
372
+ * strictBuild: true,
373
+ * });
374
+ * if (!result.ok) console.error(result.issues);
375
+ * ```
376
+ *
377
+ * @remarks Returns `{ ok: false, issues }` (does not throw) for manifest parity failures,
378
+ * missing `dist/`, LXPack validation errors, or `strictBuild` / `strictParity` warnings.
291
379
  */
292
380
  declare function packageLessonkitCourse(options: PackageLessonkitCourseOptions): Promise<PackageLessonkitCourseResult>;
293
381
 
@@ -311,6 +399,11 @@ declare function validatePackageInputs(options: Pick<PackageLessonkitCourseOptio
311
399
  }): ValidatePackageInputsResult;
312
400
  declare function remapArtifactPaths(stagingRoot: string, outDir: string, artifactPath: string | undefined): string | undefined;
313
401
 
402
+ /**
403
+ * Reject symlinks and paths escaping dist roots before packaging LMS artifacts.
404
+ */
405
+ declare function assertSpaDistContentsSafe(spaDirs: Record<string, string>, projectRoot?: string): Promise<void>;
406
+
314
407
  type LessonkitManifestPaths = {
315
408
  spaDistDir: string;
316
409
  lxpackOutDir: string;
@@ -340,4 +433,121 @@ type ParseManifestResult = {
340
433
  declare function parseLessonkitManifest(raw: unknown, label?: string, projectRoot?: string): ParseManifestResult;
341
434
  declare function loadLessonkitManifestFromFile(readJson: () => Promise<unknown>, label?: string, projectRoot?: string): Promise<ParseManifestResult>;
342
435
 
343
- export { type AssessmentDescriptor, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type FillInBlanksAssessmentDescriptor, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, extractAssessments, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };
436
+ type LkcourseEnvelopeV1 = {
437
+ format: "lkcourse";
438
+ schemaVersion: 1;
439
+ lessonkitVersion: string;
440
+ exportedAt: string;
441
+ sourceManifest: LessonkitManifest;
442
+ entries: string[];
443
+ };
444
+ type BlockTreeNodeV1 = {
445
+ type: string;
446
+ rawTag?: string;
447
+ courseId?: string;
448
+ lessonId?: string;
449
+ checkId?: string;
450
+ blockId?: string;
451
+ nodeId?: string;
452
+ children?: BlockTreeNodeV1[];
453
+ };
454
+ type BlockTreeV1 = {
455
+ schemaVersion: 1;
456
+ sources: string[];
457
+ blocks: BlockTreeNodeV1[];
458
+ };
459
+ type LkcourseValidationIssue = {
460
+ path: string;
461
+ message: string;
462
+ };
463
+ type ExportLkcourseOptions = {
464
+ projectRoot: string;
465
+ manifest: LessonkitManifest;
466
+ outPath?: string;
467
+ includeBlockTree?: boolean;
468
+ lessonkitVersion?: string;
469
+ };
470
+ type ExportLkcourseResult = {
471
+ ok: true;
472
+ archivePath: string;
473
+ fileCount: number;
474
+ includeBlockTree: boolean;
475
+ } | {
476
+ ok: false;
477
+ issues: LkcourseValidationIssue[];
478
+ };
479
+ type ValidateLkcourseResult = {
480
+ ok: true;
481
+ envelope: LkcourseEnvelopeV1;
482
+ interchange: LessonkitInterchangeV1;
483
+ } | {
484
+ ok: false;
485
+ issues: LkcourseValidationIssue[];
486
+ };
487
+ type ImportLkcourseOptions = {
488
+ archivePath: string;
489
+ targetDir: string;
490
+ };
491
+ type ImportLkcourseResult = {
492
+ ok: true;
493
+ targetDir: string;
494
+ manifest: LessonkitManifest;
495
+ interchange: LessonkitInterchangeV1;
496
+ fileCount: number;
497
+ } | {
498
+ ok: false;
499
+ issues: LkcourseValidationIssue[];
500
+ };
501
+ type ExtractBlockTreeOptions = {
502
+ projectRoot: string;
503
+ blockTypes?: string[];
504
+ appSources?: string[];
505
+ };
506
+
507
+ type ParseEnvelopeResult = {
508
+ ok: true;
509
+ envelope: LkcourseEnvelopeV1;
510
+ } | {
511
+ ok: false;
512
+ issues: LkcourseValidationIssue[];
513
+ };
514
+ declare function parseLkcourseEnvelope(raw: unknown, label?: string): ParseEnvelopeResult;
515
+
516
+ declare function extractBlockTree(options: ExtractBlockTreeOptions): BlockTreeV1;
517
+
518
+ /**
519
+ * Build a portable `.lkcourse` zip (manifest envelope + interchange + dist).
520
+ * Prefer `lessonkit export` in course projects.
521
+ *
522
+ * @example
523
+ * ```ts
524
+ * import { exportLkcourse } from "@lessonkit/lxpack";
525
+ *
526
+ * const result = await exportLkcourse({
527
+ * projectRoot: "/path/to/course",
528
+ * manifest: parsedLessonkitJson,
529
+ * archivePath: "handoff.lkcourse",
530
+ * });
531
+ * ```
532
+ */
533
+ declare function exportLkcourse(options: ExportLkcourseOptions): Promise<ExportLkcourseResult>;
534
+
535
+ declare function validateLkcourseArchiveEntries(entries: Map<string, Uint8Array>, _archiveLabel: string): ValidateLkcourseResult;
536
+ declare function validateLkcourse(archivePath: string): ValidateLkcourseResult;
537
+
538
+ /**
539
+ * Extract a `.lkcourse` archive into a project directory (manifest + dist tree).
540
+ *
541
+ * @example
542
+ * ```ts
543
+ * import { importLkcourse } from "@lessonkit/lxpack";
544
+ *
545
+ * const result = await importLkcourse({
546
+ * archivePath: "handoff.lkcourse",
547
+ * targetDir: "/path/to/dest",
548
+ * });
549
+ * ```
550
+ */
551
+ declare function importLkcourse(options: ImportLkcourseOptions): Promise<ImportLkcourseResult>;
552
+
553
+ export { type AssessmentDescriptor, type BlockTreeNodeV1, type BlockTreeV1, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type ExportLkcourseOptions, type ExportLkcourseResult, type ExtractBlockTreeOptions, type FillInBlanksAssessmentDescriptor, type ImportLkcourseOptions, type ImportLkcourseResult, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LkcourseEnvelopeV1, type LkcourseValidationIssue, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidateLkcourseResult, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assertSpaDistContentsSafe, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, exportLkcourse, extractAssessments, extractBlockTree, importLkcourse, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, parseLkcourseEnvelope, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validateLkcourse, validateLkcourseArchiveEntries, validateManifestName, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };