LXPack interoperability¶
Upgrade plan for LXPack maintainers¶
Forward-looking priorities, responsibility shifts, and API proposals for the LXPack project:
LessonKit authors React courses; LXPack validates, packages, and runs them in LMS contexts. v0.4.0 delivered the critical baseline (SPA lessons, @lxpack/api, lessonkit.json merge, in-memory assessments, lxpackBridge.v1). v0.6.0 adds packageLessonkit(), interchange schema in validators, @lxpack/spa-bridge, and interchange runtime (theme/cssVariables).
Remaining wins are conformance and optional meta-packages, not core packaging. LessonKit should keep React authoring, telemetry catalog, and thin CLI wiring.
Target end state: @lessonkit/lxpack becomes a small facade (descriptor → interchange + path helpers), or authors depend on @lxpack/api + @lxpack/lessonkit directly.
Current integration (baseline)¶
What LessonKit does today (@lessonkit/lxpack)¶
Step |
Owner today |
Notes |
|---|---|---|
Validate |
LessonKit |
Uses |
Copy Vite |
LessonKit |
|
Materialize LXPack project from interchange |
LXPack ( |
LessonKit supplies interchange + |
Emit authoring YAML (optional) |
LXPack when |
Legacy |
Build interchange JSON |
LessonKit |
|
Map theme → |
LessonKit descriptor → interchange |
LXPack resolves presets at materialize |
|
LXPack ( |
Via |
Staging + atomic promote to |
LessonKit |
Temp dir; rollback on failure |
Runtime bridge (browser) |
|
Re-exported from |
What LXPack already owns (keep)¶
SCORM 1.2 / 2004 / standalone / xAPI / cmi5 packaging
course.yamlschema + path containmentLearner shell, flow, native quiz engine, LMS APIs
SPA iframe + parent bridge host
@lxpack/tracking-schema(native LXPack courses)
Pain points driving this plan¶
Duplicate manifest authoring — LessonKit re-implements YAML generation and assessment shaping that LXPack validators already understand.
Two sources of truth for assessments — On-disk YAML and
buildCourse({ assessments }); easy to drift.Bridge contract is implicit — Score scale (0–1 vs points), method names, and versioning are documented in LessonKit, not as a typed LXPack package.
No first-class “package from interchange” API — Adapter must write a full LXPack project tree before every build.
Tracking vocabularies diverge — LessonKit
telemetryevents vs LXPacktrack()/ xAPI export paths are aligned by convention, not schema.Preview gap — Authors use Vite for dev; LXPack preview requires a materialized project; parity testing is manual.
Conformance is one-sided — LessonKit 0.9.x plans Playwright parity tests; LXPack has no shared fixture contract.
Recommended division of responsibility¶
flowchart TB
subgraph lk [LessonKit — keep]
REACT["@lessonkit/react\ncomponents, hooks, a11y"]
CORE["@lessonkit/core\nids, telemetry catalog"]
XAPI["@lessonkit/xapi\nauthor-time statements"]
CLI["@lessonkit/cli\ninit, dev, vite build"]
end
subgraph lxp [LXPack — expand]
API["@lxpack/api\nvalidate, build, packageLessonkit"]
VAL["@lxpack/validators\nlessonkit interchange schema"]
BRIDGE["@lxpack/spa-bridge\ntyped parent/child SDK"]
RT["@lxpack/runtime\niframe host + LMS APIs"]
PKG["@lxpack/scorm, xapi, cmi5"]
CONF["@lxpack/conformance\nshared fixtures + matrix"]
end
subgraph thin [Thin adapter — shrink]
LKL["@lessonkit/lxpack\noptional: descriptor → interchange only"]
end
REACT --> LKL
CLI --> LKL
LKL --> API
API --> VAL
API --> PKG
RT --> BRIDGE
PKG --> LMS["LMS / LRS"]
RT --> LMS
Concern |
Should live in |
Rationale |
|---|---|---|
React components, block catalog, WCAG helpers |
LessonKit |
Authoring UX and Studio (future) |
|
LessonKit ( |
Framework identity; LXPack should accept ids, not define pedagogy |
Interchange schema ( |
LXPack validators |
Single schema for any React toolchain, not only LessonKit |
Materialize SPA + |
LXPack API |
Removes YAML emitters from LessonKit |
Assessment normalization (MCQ shape, passingScore semantics) |
LXPack validators |
One canonical assessment model at build time |
SCORM/xAPI/cmi5 ZIP creation |
LXPack |
Already core competency |
|
LXPack ( |
SPA authors (LessonKit or not) import one package |
Map LessonKit telemetry → bridge / |
LessonKit ( |
Framework knows event names; calls LXPack SDK |
Theme token → |
LXPack (generic) + LessonKit preset map (thin) |
LXPack should not depend on |
End-to-end conformance fixtures |
Shared repo or |
Both CI pipelines run the same matrix |
|
LessonKit |
UX wrapper calling LXPack API |
Proposed LXPack upgrades (prioritized)¶
P0 — Package LessonKit without a hand-built project tree¶
Problem: @lessonkit/lxpack writes course.yaml, assessment YAML, copies dist/, writes lessonkit.json, then calls buildCourse. LessonKit maintains parallel YAML emitters.
Proposal: Add to @lxpack/api:
import type { ExportTarget } from "@lxpack/api";
export type PackageLessonkitOptions = {
/** Merged interchange + course metadata (see schema below). */
interchange: LessonkitInterchangeV1;
/** SPA payloads: lesson id → absolute path to folder with index.html */
spaDirs: Record<string, string>;
/** Optional in-memory assessments (same shape as buildCourse today). */
assessments?: AssessmentInput[];
target: ExportTarget;
/** Output zip or directory; optional staging courseDir for debugging */
output?: string;
dir?: boolean;
courseDir?: string; // default: temp; kept on failure if debug: true
};
export type PackageLessonkitResult =
| { ok: true; outputPath?: string; outputDir?: string; fileCount: number; courseDir: string }
| { ok: false; issues: Array<{ path?: string; message: string; severity?: "error" | "warning" }> };
export function packageLessonkit(options: PackageLessonkitOptions): Promise<PackageLessonkitResult>;
LXPack responsibilities:
Generate
course.yamlinternally from interchange (no consumer YAML emitter).Copy SPA dirs with path containment (reuse existing rules).
Prefer only in-memory
assessmentsfor LessonKit-sourced quizzes; skip writingassessments/*.yamlunlesswriteAuthoringFiles: true.Return structured issues (same shape as
validateCourse).
Acceptance criteria:
examples/lessonkit-spabuilds using only@lxpack/api(no checked-incourse.yamlrequired for LessonKit path).LessonKit deletes
yaml.ts,assessmentYaml.ts, and most ofwriteProject.ts.CI: golden LessonKit course packages identically before/after migration (ZIP hash or manifest comparison).
LessonKit follow-up: packageLessonkitCourse() becomes a thin wrapper mapping LessonkitCourseDescriptor → PackageLessonkitOptions.
P0 — Formalize lxpackBridge as @lxpack/spa-bridge¶
Problem: Bridge types and score normalization live in @lessonkit/lxpack/bridge. Non-LessonKit SPAs duplicate logic; versioning is informal.
Proposal: New package (or @lxpack/runtime/bridge export):
// Host (LXPack runtime) — register once
export function createLxpackBridgeHost(options: BridgeHostOptions): LxpackBridgeV1;
// Child (SPA) — safe access from iframe
export function getLxpackBridge(): LxpackBridgeV1 | null;
export function normalizeScore(raw: { score: number; maxScore?: number }): number | null;
export function normalizePassingThreshold(raw: { passingScore?: number; maxScore?: number }): number;
export type LxpackBridgeV1 = {
completeLesson(lessonId: string): void;
completeCourse(): void;
submitAssessment(payload: { id: string; score: number; passingScore?: number }): void;
track?(event: TrackingSchemaEvent): void;
};
Document in LXPack docs:
Method |
Score / threshold scale |
When to call |
|---|---|---|
|
0–1 scaled |
After quiz graded in SPA |
YAML |
absolute points |
Native LXPack quizzes only |
Versioning: Keep window.parent.lxpackBridge.v1; add v2 alongside with a capability negotiation helper (bridge.supportedVersions).
Acceptance criteria:
Published TypeScript types on npm.
examples/lessonkit-spaimports child SDK from@lxpack/spa-bridge.LessonKit removes duplicate
bridge.tsand depends on LXPack package.Validator warns when SPA
index.htmlreferences deprecatedwindow.parent.lxpackwithout bridge.
P1 — Own the lessonkit.json interchange schema¶
Problem: Schema is implied by LessonKit’s LessonkitInterchangeV1 type; LXPack merges file at build time but does not publish a versioned JSON Schema / Zod module.
Proposal:
Add
@lxpack/validators/lessonkit(orlessonkitInterchangeSchemaexport).Document fields:
{
"format": "lessonkit",
"version": "1",
"course": { "id": "course-id", "title": "Title" },
"lessons": [{ "id": "lesson-id", "title": "...", "type": "spa", "path": "dist" }],
"assessments": [{ "id": "check-id", "passingScore": 1, "questions": [] }],
"tracking": { "completion": { "threshold": 1 } },
"runtime": { "theme": "default", "cssVariables": { "--lk-color-primary": "#2563eb" } }
}
validateCourseaccepts interchange-only projects (generates missingcourse.yaml).Breaking changes bump
version: "2"with migration notes.
Shift from LessonKit: Stop emitting interchange by hand in descriptorToInterchange; optionally generate from descriptor in LessonKit until descriptors are deprecated.
Acceptance criteria:
JSON Schema published under
docs/reference/lessonkit-interchange.md.Invalid interchange fails
validateCoursewith path-qualified errors.LessonKit CI imports schema from
@lxpack/validators(devDependency) instead of duplicating rules.
P1 — Unified tracking map (LessonKit telemetry ↔ LXPack)¶
Problem: LessonKit emits lesson_completed, quiz_completed, etc. (@lessonkit/core catalog). LXPack has @lxpack/tracking-schema. Adapters guess mappings for bridge and xAPI.
Proposal:
Publish
mapLessonkitTelemetryToLxpack(event): TrackingSchemaEvent | nullin@lxpack/tracking-schema(or@lxpack/api).Publish verb / activity IRI recommendations for packaged courses (xAPI export).
Optional:
bridge.track()accepts canonical events so SPAs can forward rich telemetry without custom LMS code.
Reference mapping (starter):
LessonKit |
LXPack / xAPI intent |
|---|---|
|
course initialized |
|
course completed |
|
lesson initialized |
|
|
|
interaction / answered |
|
|
|
|
Acceptance criteria:
Table is documented and unit-tested in LXPack.
LessonKit
@lessonkit/reactuses exported mapper (delete bespoke switch inlxpackBridge.ts).xAPI ZIPs from LessonKit courses use consistent activity ids derived from interchange
course.id/ lesson ids.
P1 — Theme interchange without @lessonkit/themes¶
Problem: themeToLxpackRuntime() in LessonKit depends on @lessonkit/themes to produce runtime.cssVariables.
Proposal:
Interchange carries optional
runtime.cssVariables(already natural in YAML).LXPack applies variables to learner shell (already supports
runtime.cssVariablesincourse.yaml).Optional:
runtime.themePreset: "lessonkit:brand"resolved via a registered preset table in LXPack or passed fully expanded in interchange.
Shift: LessonKit only expands presets at package time (one function), or authors commit expanded variables in lessonkit.json. LXPack does not import LessonKit packages.
P2 — Preview and validate from SPA build output¶
Problem: Developers run lessonkit dev (Vite) but must materialize .lxpack/course to use lxpack preview with LMS chrome.
Proposal:
lxpack preview --lessonkit ./lessonkit.json --spa dist/
Starts runtime with SPA lesson iframe + bridge host.
Optional SCORM simulator flags (existing
lxpack.config.jsonpreview modes).
Acceptance criteria:
Documented workflow in LessonKit interoperability guide.
No
assessments/*.yamlrequired on disk when passing--assessmentsJSON path or embedded in interchange.
P2 — SCORM layout recipes for LessonKit¶
Problem: LessonKit supports single-spa (one SCO, in-app navigation) vs per-lesson-spa (multi-SCO). Authors lack LXPack guidance on SCORM 2004 sequencing for each.
Proposal:
Document recipes in LXPack:
Recipe A — Single SCO SPA (default LessonKit): one
type: spalesson; completion via bridge.Recipe B — Multi SCO: one SPA folder per
lessonId; flow optional; maplesson_completedper SCO.
Validators emit warnings when interchange lessons omit
pathor id collisions would break SCORM 2004.Optional:
buildCourse({ scormLayout: "single-sco-spa" | "multi-sco-spa" })expands interchange automatically.
Open question for maintainers: Should multi-lesson React apps ever share one SPA build (hash router), or should LXPack enforce per-lesson builds for true multi-SCO?
P3 — Optional @lxpack/lessonkit meta-package¶
Problem: Consumers install @lessonkit/lxpack + @lxpack/api and must understand Node 18+, interchange, bridge.
Proposal:
@lxpack/lessonkitre-exportspackageLessonkit, bridge SDK, schema types.Peer dependency:
reactnot required (packaging only).LessonKit deprecates
@lessonkit/lxpackover a major version with migration guide.
What should stay in LessonKit (non-goals for LXPack)¶
React component library and hooks (
Course,Lesson,Quiz, …).Authoring-time telemetry sinks and
@lessonkit/xapiclient (distinct from LMS-export xAPI inside LXPack).Vite template,
lessonkit init,lessonkit dev,lessonkit build.Block catalog for AI/Studio (
block-catalog.v1.json).WCAG primitives (
@lessonkit/accessibility).
Non-goals (both projects):
Merging repositories.
Replacing LXPack markdown/HTML authoring with LessonKit-only workflows.
Re-implementing SCORM manifest generation in LessonKit.
Suggested LXPack release sequence¶
Release |
Theme |
Status |
|---|---|---|
v0.5.0 |
Thin packaging |
Shipped — |
v0.5.x |
Bridge SDK |
Shipped — |
v0.6.0 |
Tracking + theme |
Shipped — interchange |
v0.6.x |
Conformance |
Planned — shared fixtures package, SCORM recipes |
v0.7.0 |
Optional meta-package |
Planned — |
Coordinate with LessonKit 0.9.x (conformance harness) and 1.0.0 (stable public API).
API stability commitments (request to LXPack)¶
LessonKit 1.0.0 needs these to remain stable (or versioned with migration):
lxpackBridge.v1method signatures and 0–1 score semantics forsubmitAssessment.lessonkit.jsonformat+versionwith documented migration path.ExportTargetenum andbuildCourse/packageLessonkitresult shapes.SPA lesson
type: spa+pathpointing at folder withindex.html.
How to validate with LessonKit today¶
Maintainers can verify changes against the LessonKit repo without adopting the full monorepo:
git clone https://github.com/eddiethedean/lessonkit.git
cd lessonkit
npm ci
npm run build
npm -w lessonkit-example-lxpack-golden run build
npm -w lessonkit-example-lxpack-golden run package:scorm12
Artifacts: examples/lxpack-golden/.lxpack/course/.lxpack/out/course-scorm12.zip
Contact surface: open issues in either repo with label interop/lessonkit; attach interchange JSON and buildCourse / packageLessonkit structured errors.
Summary for LXPack maintainers¶
Absorb project materialization —
packageLessonkit()so adapters stop writing YAML by hand.Own interchange + bridge — schema, typed SDK, explicit score semantics.
Publish tracking maps — one table from LessonKit telemetry to LXPack/LRS.
Ship shared conformance — both projects gate releases on the same fixture matrix.
Keep LessonKit thin — React authoring only; LMS delivery stays in LXPack.
Historical checklist (LessonKit team)¶
What LessonKit requested before LXPack v0.4.0, and integration status from the LessonKit side:
the improvements we wanted in LXPack so it works better as the packaging and LMS export layer for LessonKit, plus what LessonKit should do next.
Status¶
LXPack v0.4.0 — baseline SPA +
@lxpack/api+lessonkit.jsonmerge (historical checklist below).LXPack v0.6.0 —
packageLessonkit(), interchange schema in@lxpack/validators,@lxpack/spa-bridge,@lxpack/tracking-schematelemetry map, interchangeruntime+assessments. LessonKit 0.8.2 integrates these (^0.6.0); see maintainer upgrade plan.
LessonKit is React-first authoring (@lessonkit/react). LXPack is a manifest-driven compiler and
runtime (course.yaml, markdown/HTML/component lessons, SCORM/xAPI/cmi5 export). The two projects
are complementary: LessonKit owns the developer experience; LXPack owns validation, preview, and LMS
artifacts.
Related LessonKit docs:
ROADMAP.md— integration strategy (0.6.0+)SPEC.md— LessonKit technical specPLAN.md— product vision
Current integration plan (LessonKit side)¶
LessonKit’s preferred path is Strategy A from the roadmap:
Author courses in React with
@lessonkit/react.Export to an LXPack project via
@lessonkit/lxpack(shipped in 0.6.0 — see Packaging reference).Run
lxpack validateandlxpack build --target …for LMS delivery (viavalidateLessonkitProject/packageLessonkitCourseor the golden example scripts).
The adapter maps a LessonkitCourseDescriptor plus built SPA assets into LXPack’s course.yaml and lessonkit.json; multi-lesson UX stays in your React app for single-spa layouts.
What changed in LXPack v0.4.0 (impact on LessonKit)¶
Because LXPack now implements the features we previously asked for, LessonKit should treat LXPack as the default packaging toolchain and focus on building a thin, well-tested adapter.
Recommended LessonKit next steps:
~~Create
@lessonkit/lxpack~~ — done (0.6.0).~~Decide a stable mapping for identities~~ — done (identity v1; see Identity reference).
~~Add at least one end-to-end example~~ — done (](https://github.com/eddiethedean/lessonkit/tree/main/examples/lxpack-golden/)).
~~Add a CI smoke test that runs LXPack packaging for that example~~ — done (
.github/workflows/checks.ymlpackaging job; integration; e2e).
Design goals for interoperability¶
Goal |
Why it matters |
|---|---|
Preserve React authoring |
LessonKit users should not rewrite courses as YAML/markdown to ship to an LMS. |
Stable identity model |
|
Shared tracking semantics |
Completion, quiz pass/fail, and time-on-task should mean the same thing in both runtimes. |
Programmatic packaging |
|
npm-first consumption |
LessonKit uses npm workspaces; LXPack packages should install cleanly without requiring pnpm for consumers. |
Gap analysis¶
2. No first-class “hosted React bundle” lesson type¶
LXPack can package standalone web apps, but there is no documented lesson type for:
A Vite/React build output as a lesson SCO with known entry (
index.html)Wiring that lesson into
flow, completion rules, and multi-SCO SCORM 2004
Pain: LessonKit’s natural artifact is a built SPA, not a folder of markdown files.
3. CLI-centric integration surface¶
LXPack’s primary interface is @lxpack/cli (init, preview, validate, build). LessonKit
needs:
validateCourse(project)/buildCourse(project, target)as importable functionsTyped options and structured errors (for CI and
@lessonkit/lxpack)
Pain: Subprocess + stdout parsing is fragile for monorepo CI and IDE integrations.
4. Tracking and xAPI vocabulary alignment¶
LessonKit (0.1.x) emits telemetry events and minimal xAPI statements (started, completed).
LXPack has mature tracking, completion thresholds, quiz YAML, and export-time embedding.
Pain: Without a shared event/verb map, adapters guess at semantics and LRS reports diverge.
5. Assessment model differences¶
LXPack |
LessonKit |
|---|---|
Author YAML in |
Inline |
|
Simple correct/incorrect + |
Pain: Export must invent assessment YAML from React props or lose quiz metadata.
6. Theming and accessibility¶
LessonKit targets WCAG 2.1 AA with React semantics and @lessonkit/accessibility helpers. LXPack
runtime uses markdown sanitization, HTML interactions, and runtime.theme CSS classes.
Pain: Branding and a11y behavior may differ between preview (LXPack) and author preview (LessonKit/Vite) unless theme contracts align.
Recommended (now implemented) LXPack capabilities¶
These were originally prioritized upgrade requests. With LXPack v0.4.0 implementing them, they are now the capabilities LessonKit should lean on.
P0 — React / SPA lesson type¶
Now: Use the SPA/React lesson type to package LessonKit’s built output without rewriting lessons as markdown.
lessons:
- id: phishing-101
title: Phishing Awareness
type: spa
path: dist/lessons/phishing-101 # folder with index.html + assets
runtime:
mount: root # optional; default #root
Behavior:
Package the folder as a launchable unit in standalone, SCORM 1.2, SCORM 2004 (SCO), xAPI, cmi5.
Expose a stable parent bridge (
window.parent.lxpackorpostMessage) for:completeLesson({ lessonId })reportAssessment({ id, score, passed })optional xAPI statement passthrough
Why: Lets LessonKit ship vite build output per lesson without converting UI to markdown.
LessonKit integration notes:
Prefer a stable bridge surface (for completion, scoring, and optional statement passthrough).
Keep LessonKit as the “authoring runtime”; let LXPack own LMS packaging and launch surfaces.
P0 — Programmatic build and validate API¶
Now: Prefer importing validate/build APIs from LXPack in @lessonkit/lxpack instead of shelling
out to lxpack via subprocess.
import { validateCourse, buildCourse } from "@lxpack/api";
const result = await validateCourse({ courseDir: "/path/to/course", target: "scorm12" });
const artifact = await buildCourse({ courseDir, target: "scorm2004", output: "./out.zip" });
Requirements:
Structured result:
{ ok, errors: [{ path, rule, message }], warnings }No global process cwd assumptions; all paths explicit
Works when imported from npm (LessonKit) without pnpm
Why: This keeps LessonKit packaging deterministic, testable, and easy to integrate into CI.
P1 — Import / interchange schema (lessonkit.json or lxpack.import)¶
Now: Use the interchange format (if provided by LXPack) to avoid duplicating metadata between
LessonKit and course.yaml.
{
"format": "lessonkit",
"version": "1",
"course": { "id": "cyber-basics", "title": "Cybersecurity Basics" },
"lessons": [
{
"id": "phishing-101",
"title": "Phishing Awareness",
"type": "spa",
"build": { "command": "npm run build", "outputDir": "dist" }
}
],
"assessments": [],
"tracking": { "completion": { "threshold": 0.9 } }
}
Behavior:
lxpack validatemerges interchange + generatedcourse.yaml(or generates yaml at build time).Validators understand LessonKit ids and required fields.
Why: Reduces duplication between LessonKit metadata and hand-maintained course.yaml.
P1 — Assessment interchange from structured data¶
Now: Prefer structured assessment interchange/build-time injection so LessonKit can export quiz metadata without writing author-only files into the learner artifact.
buildCourse({
courseDir,
target: "scorm12",
assessments: [{ id: "final_quiz", questions: [...] }], // validated by @lxpack/validators
});
Why: @lessonkit/lxpack can extract Quiz props / config from React without writing
assessments/*.yaml to disk.
P2 — Plugin slot for custom lesson runtimes¶
Now: Use LXPack’s plugin/runtime extension points (if shipped) to avoid forking LXPack lesson types just to support LessonKit.
registerLessonRuntime("lessonkit-react", {
validate(lesson, ctx) { ... },
bundle(lesson, ctx) { ... },
preview(lesson, ctx) { ... },
});
Why: LessonKit can register a runtime once instead of forking LXPack lesson types.
P2 — Theme token bridge¶
Now: Use LXPack’s theme bridge (if shipped) so LessonKit themes carry through to packaged artifacts.
runtime:
theme: lessonkit-default
cssVariables:
--lk-color-primary: "#2563eb"
Why: Visual parity between LessonKit dev preview and LXPack-packaged learner view.
P3 — Documentation and examples¶
If not already present in LXPack docs, add:
Guide: “Package a React (LessonKit) course”
Example repo:
examples/lessonkit-spa/with Vite build +lxpack buildMigration table: LessonKit component → LXPack lesson type
Suggested division of responsibility¶
flowchart TB
subgraph author [Authoring]
LK["LessonKit React app\n(@lessonkit/react)"]
end
subgraph bridge [Bridge - planned]
LKL["@lessonkit/lxpack\nexport + metadata"]
end
subgraph lxpack [LXPack]
VAL["@lxpack/validators"]
CLI["@lxpack/cli / @lxpack/api"]
PKG["@lxpack/scorm / xapi / cmi5"]
RT["@lxpack/runtime"]
end
subgraph lms [Delivery]
LMS["LMS / LRS / browser"]
end
LK --> LKL
LKL --> VAL
LKL --> CLI
CLI --> PKG
PKG --> LMS
RT --> LMS
Layer |
Owner |
Responsibility |
|---|---|---|
Authoring UX |
LessonKit |
Components, hooks, a11y, Vite templates |
Export adapter |
|
Build SPA(s), emit interchange + invoke LXPack |
Validation & packaging |
LXPack |
Schema, path containment, SCORM/xAPI/cmi5 ZIPs |
Learner runtime |
LXPack (+ SPA bridge) |
Navigation, flow, LMS APIs, quiz engine where applicable |
Phased rollout (cross-repo)¶
Phase |
LXPack |
LessonKit |
|---|---|---|
1 |
Document SPA lesson type + bridge API (even if experimental) |
Spike |
2 |
Ship |
Wire |
3 |
Tracking schema + assessment build injection |
Align |
4 |
Plugin runtime registration |
Optional: embed |
Non-goals (for now)¶
Merging the two repos into one monorepo
Replacing LXPack markdown authoring with LessonKit-only workflows
Requiring LessonKit authors to learn full
course.yamlbefore they can ship
Open questions for LXPack maintainers¶
Single-SCO vs multi-SCO: Should a LessonKit
Coursemap to one SCORM package or one SCO perLesson?Answer keys in SPA lessons: Should quiz scoring stay in LXPack runtime only, or allow client-side scoring inside the SPA with signed/embedded config?
Versioning: How should
lxpackBridge.v1evolve without breaking published LessonKit courses?npm vs pnpm: Can release CI guarantee
@lxpack/*packages work as npm dependencies in LessonKit’s workspace?
Summary¶
LXPack already solves problems LessonKit should not rebuild (SCORM manifests, ZIP packaging, xAPI/cmi5, validation, preview). With LXPack v0.4.0 implementing the suggested features, the highest-value work for LessonKit is now:
Build
@lessonkit/lxpackas the packaging adapterShip one end-to-end SCORM export example
Lock down identity + tracking mappings (course/lesson/assessment ids)
That delivers LMS-ready packages without forcing authors out of React.