coursecode 0.1.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/LICENSE +21 -0
- package/README.md +322 -0
- package/THIRD_PARTY_NOTICES.md +22 -0
- package/bin/cli.js +331 -0
- package/framework/assets/logo-coursecode-black.svg +14 -0
- package/framework/assets/logo-coursecode-white.svg +14 -0
- package/framework/assets/logo-coursecode.svg +14 -0
- package/framework/css/01-base.css +160 -0
- package/framework/css/02-layout.css +499 -0
- package/framework/css/accessibility.css +834 -0
- package/framework/css/components/accordions.css +710 -0
- package/framework/css/components/assessments.css +520 -0
- package/framework/css/components/audio-player.css +570 -0
- package/framework/css/components/badges.css +80 -0
- package/framework/css/components/breadcrumbs.css +87 -0
- package/framework/css/components/buttons.css +707 -0
- package/framework/css/components/callouts.css +1280 -0
- package/framework/css/components/cards.css +475 -0
- package/framework/css/components/carousel.css +193 -0
- package/framework/css/components/checkbox-group.css +123 -0
- package/framework/css/components/checklist.css +203 -0
- package/framework/css/components/collapse.css +96 -0
- package/framework/css/components/comparison.css +33 -0
- package/framework/css/components/content-image.css +36 -0
- package/framework/css/components/document-gallery.css +425 -0
- package/framework/css/components/dropdown.css +115 -0
- package/framework/css/components/embed-frame.css +142 -0
- package/framework/css/components/engagement.css +412 -0
- package/framework/css/components/features.css +35 -0
- package/framework/css/components/flip-cards.css +253 -0
- package/framework/css/components/footer.css +353 -0
- package/framework/css/components/forms.css +294 -0
- package/framework/css/components/hero.css +216 -0
- package/framework/css/components/images.css +528 -0
- package/framework/css/components/interactive-timeline.css +274 -0
- package/framework/css/components/intro-cards.css +30 -0
- package/framework/css/components/lightbox.css +666 -0
- package/framework/css/components/loading.css +65 -0
- package/framework/css/components/modals.css +235 -0
- package/framework/css/components/notifications.css +107 -0
- package/framework/css/components/quote.css +150 -0
- package/framework/css/components/sidebar.css +684 -0
- package/framework/css/components/slide-header.css +52 -0
- package/framework/css/components/spinner.css +62 -0
- package/framework/css/components/stats.css +44 -0
- package/framework/css/components/steps.css +232 -0
- package/framework/css/components/tables.css +90 -0
- package/framework/css/components/tabs.css +347 -0
- package/framework/css/components/timeline.css +154 -0
- package/framework/css/components/toggle.css +95 -0
- package/framework/css/components/tooltip.css +226 -0
- package/framework/css/components/video-player.css +438 -0
- package/framework/css/design-tokens.css +707 -0
- package/framework/css/framework.css +86 -0
- package/framework/css/interactions/accessibility.css +75 -0
- package/framework/css/interactions/base.css +92 -0
- package/framework/css/interactions/drag-drop.css +295 -0
- package/framework/css/interactions/fill-in-the-blank.css +236 -0
- package/framework/css/interactions/hotspots.css +69 -0
- package/framework/css/interactions/index.css +45 -0
- package/framework/css/interactions/interactive-image.css +359 -0
- package/framework/css/interactions/likert.css +126 -0
- package/framework/css/interactions/matching.css +354 -0
- package/framework/css/interactions/numeric-input.css +78 -0
- package/framework/css/interactions/sequencing.css +378 -0
- package/framework/css/interactions/true-false.css +177 -0
- package/framework/css/layouts/article.css +258 -0
- package/framework/css/layouts/base.css +30 -0
- package/framework/css/layouts/canvas.css +38 -0
- package/framework/css/layouts/focused.css +236 -0
- package/framework/css/layouts/index.css +29 -0
- package/framework/css/layouts/presentation.css +191 -0
- package/framework/css/layouts/traditional.css +52 -0
- package/framework/css/responsive.css +439 -0
- package/framework/css/utilities/accessibility-utils.css +59 -0
- package/framework/css/utilities/animations.css +419 -0
- package/framework/css/utilities/borders.css +72 -0
- package/framework/css/utilities/colors.css +76 -0
- package/framework/css/utilities/container.css +46 -0
- package/framework/css/utilities/decorative.css +442 -0
- package/framework/css/utilities/display.css +257 -0
- package/framework/css/utilities/flexbox.css +80 -0
- package/framework/css/utilities/grid.css +69 -0
- package/framework/css/utilities/icons.css +534 -0
- package/framework/css/utilities/lists.css +190 -0
- package/framework/css/utilities/spacing.css +167 -0
- package/framework/css/utilities/tables.css +81 -0
- package/framework/css/utilities/typography.css +159 -0
- package/framework/css/utilities/visibility.css +117 -0
- package/framework/docs/COURSE_AUTHORING_GUIDE.md +1773 -0
- package/framework/docs/COURSE_OUTLINE_GUIDE.md +725 -0
- package/framework/docs/COURSE_OUTLINE_TEMPLATE.md +161 -0
- package/framework/docs/DATA_MODEL.md +409 -0
- package/framework/docs/FRAMEWORK_GUIDE.md +1088 -0
- package/framework/docs/USER_GUIDE.md +583 -0
- package/framework/docs/examples/cloudflare-channel-relay.js +169 -0
- package/framework/docs/examples/cloudflare-data-worker.js +102 -0
- package/framework/docs/examples/cloudflare-error-worker.js +228 -0
- package/framework/index.html +175 -0
- package/framework/js/app/AppActions.js +410 -0
- package/framework/js/app/AppState.js +225 -0
- package/framework/js/app/AppUI.js +616 -0
- package/framework/js/assessment/AssessmentActions.js +615 -0
- package/framework/js/assessment/AssessmentFactory.js +471 -0
- package/framework/js/assessment/AssessmentState.js +322 -0
- package/framework/js/assessment/AssessmentUI.js +451 -0
- package/framework/js/automation/api-engagement.js +196 -0
- package/framework/js/automation/api-interactions.js +167 -0
- package/framework/js/automation/api.js +242 -0
- package/framework/js/automation/index.js +41 -0
- package/framework/js/components/interactions/drag-drop.js +884 -0
- package/framework/js/components/interactions/fill-in.js +535 -0
- package/framework/js/components/interactions/hotspot.js +702 -0
- package/framework/js/components/interactions/interaction-base.js +511 -0
- package/framework/js/components/interactions/likert.js +301 -0
- package/framework/js/components/interactions/matching.js +699 -0
- package/framework/js/components/interactions/multiple-choice.js +377 -0
- package/framework/js/components/interactions/numeric.js +271 -0
- package/framework/js/components/interactions/sequencing.js +423 -0
- package/framework/js/components/interactions/true-false.js +241 -0
- package/framework/js/components/ui-components/accordion.js +442 -0
- package/framework/js/components/ui-components/alert.js +88 -0
- package/framework/js/components/ui-components/audio-player.js +1193 -0
- package/framework/js/components/ui-components/callout.js +121 -0
- package/framework/js/components/ui-components/carousel.js +145 -0
- package/framework/js/components/ui-components/checkbox-group.js +87 -0
- package/framework/js/components/ui-components/checklist.js +40 -0
- package/framework/js/components/ui-components/collapse.js +114 -0
- package/framework/js/components/ui-components/comparison.js +30 -0
- package/framework/js/components/ui-components/conditional-display.js +150 -0
- package/framework/js/components/ui-components/content-image.js +41 -0
- package/framework/js/components/ui-components/dropdown.js +262 -0
- package/framework/js/components/ui-components/embed-frame.js +274 -0
- package/framework/js/components/ui-components/features.js +33 -0
- package/framework/js/components/ui-components/flip-card.js +230 -0
- package/framework/js/components/ui-components/form-validator.js +76 -0
- package/framework/js/components/ui-components/hero.js +49 -0
- package/framework/js/components/ui-components/index.js +12 -0
- package/framework/js/components/ui-components/interactive-image.js +235 -0
- package/framework/js/components/ui-components/interactive-timeline.js +285 -0
- package/framework/js/components/ui-components/intro-cards.js +35 -0
- package/framework/js/components/ui-components/lightbox.js +652 -0
- package/framework/js/components/ui-components/modal.js +386 -0
- package/framework/js/components/ui-components/notifications.js +145 -0
- package/framework/js/components/ui-components/progress.js +88 -0
- package/framework/js/components/ui-components/quote.js +41 -0
- package/framework/js/components/ui-components/stats.js +33 -0
- package/framework/js/components/ui-components/steps.js +41 -0
- package/framework/js/components/ui-components/tabs.js +255 -0
- package/framework/js/components/ui-components/timeline.js +42 -0
- package/framework/js/components/ui-components/toggle-group.js +73 -0
- package/framework/js/components/ui-components/tooltip.js +458 -0
- package/framework/js/components/ui-components/value-display.js +133 -0
- package/framework/js/components/ui-components/video-player.js +686 -0
- package/framework/js/core/component-catalog.js +121 -0
- package/framework/js/core/event-bus.js +178 -0
- package/framework/js/core/interaction-catalog.js +149 -0
- package/framework/js/dev/runtime-linter.js +1725 -0
- package/framework/js/drivers/cmi5-driver.js +768 -0
- package/framework/js/drivers/driver-factory.js +77 -0
- package/framework/js/drivers/driver-interface.js +110 -0
- package/framework/js/drivers/http-driver-base.js +241 -0
- package/framework/js/drivers/lti-driver.js +508 -0
- package/framework/js/drivers/proxy-driver.js +444 -0
- package/framework/js/drivers/scorm-12-driver.js +560 -0
- package/framework/js/drivers/scorm-2004-driver.js +775 -0
- package/framework/js/drivers/scorm-driver-base.js +112 -0
- package/framework/js/engagement/engagement-manager.js +404 -0
- package/framework/js/engagement/engagement-progress.js +191 -0
- package/framework/js/engagement/engagement-trackers.js +215 -0
- package/framework/js/engagement/requirement-strategies.js +268 -0
- package/framework/js/main.js +727 -0
- package/framework/js/managers/accessibility-manager.js +499 -0
- package/framework/js/managers/assessment-manager.js +230 -0
- package/framework/js/managers/audio-manager.js +944 -0
- package/framework/js/managers/comment-manager.js +88 -0
- package/framework/js/managers/flag-manager.js +86 -0
- package/framework/js/managers/interaction-manager.js +254 -0
- package/framework/js/managers/interaction-registry.js +96 -0
- package/framework/js/managers/objective-manager.js +423 -0
- package/framework/js/managers/score-manager.js +441 -0
- package/framework/js/managers/video-manager.js +536 -0
- package/framework/js/navigation/Breadcrumbs.js +234 -0
- package/framework/js/navigation/NavigationActions.js +1132 -0
- package/framework/js/navigation/NavigationState.js +276 -0
- package/framework/js/navigation/NavigationUI.js +574 -0
- package/framework/js/navigation/document-gallery.js +357 -0
- package/framework/js/navigation/navigation-helpers.js +175 -0
- package/framework/js/navigation/navigation-validators.js +174 -0
- package/framework/js/state/index.js +8 -0
- package/framework/js/state/lms-connection.js +482 -0
- package/framework/js/state/lms-error-utils.js +58 -0
- package/framework/js/state/state-commits.js +200 -0
- package/framework/js/state/state-domains.js +86 -0
- package/framework/js/state/state-manager.js +502 -0
- package/framework/js/state/state-validation.js +311 -0
- package/framework/js/state/transaction-log.js +41 -0
- package/framework/js/state/xapi-statement-service.js +325 -0
- package/framework/js/utilities/access-control.js +99 -0
- package/framework/js/utilities/breakpoint-manager.js +315 -0
- package/framework/js/utilities/canvas-slide.js +35 -0
- package/framework/js/utilities/conditional-display.js +388 -0
- package/framework/js/utilities/course-channel.js +214 -0
- package/framework/js/utilities/course-helpers.js +420 -0
- package/framework/js/utilities/data-reporter.js +273 -0
- package/framework/js/utilities/error-reporter.js +313 -0
- package/framework/js/utilities/hotspot-helper.js +341 -0
- package/framework/js/utilities/icons.js +348 -0
- package/framework/js/utilities/logger.js +92 -0
- package/framework/js/utilities/markdown-renderer.js +45 -0
- package/framework/js/utilities/scroll-tracker.js +68 -0
- package/framework/js/utilities/ui-initializer.js +146 -0
- package/framework/js/utilities/utilities.js +293 -0
- package/framework/js/utilities/view-manager.js +227 -0
- package/framework/js/validation/html-validators.js +422 -0
- package/framework/js/validation/scorm-validators.js +438 -0
- package/framework/js/vendor/pipwerks.js +931 -0
- package/framework/scripts/generate-narration.js +629 -0
- package/framework/scripts/tts-providers/azure-provider.js +178 -0
- package/framework/scripts/tts-providers/base-provider.js +81 -0
- package/framework/scripts/tts-providers/deepgram-provider.js +135 -0
- package/framework/scripts/tts-providers/elevenlabs-provider.js +148 -0
- package/framework/scripts/tts-providers/google-provider.js +272 -0
- package/framework/scripts/tts-providers/index.js +158 -0
- package/framework/scripts/tts-providers/openai-provider.js +143 -0
- package/framework/version.json +63 -0
- package/lib/authoring-api.js +919 -0
- package/lib/build-linter.js +450 -0
- package/lib/build-packaging.js +186 -0
- package/lib/build.js +88 -0
- package/lib/cloud.js +691 -0
- package/lib/convert.js +341 -0
- package/lib/course-parser.js +936 -0
- package/lib/course-writer.js +258 -0
- package/lib/create.js +248 -0
- package/lib/css-index.js +237 -0
- package/lib/dev.js +51 -0
- package/lib/export-content.js +1246 -0
- package/lib/headless-browser.js +413 -0
- package/lib/import.js +377 -0
- package/lib/index.js +80 -0
- package/lib/info.js +79 -0
- package/lib/interaction-formatters.js +568 -0
- package/lib/manifest/cmi5-manifest.js +63 -0
- package/lib/manifest/lti-tool-config.js +53 -0
- package/lib/manifest/manifest-factory.js +99 -0
- package/lib/manifest/scorm-12-manifest.js +61 -0
- package/lib/manifest/scorm-2004-manifest.js +94 -0
- package/lib/manifest/scorm-proxy-manifest.js +104 -0
- package/lib/manifest-parser.js +96 -0
- package/lib/mcp-prompts.js +753 -0
- package/lib/mcp-server.js +316 -0
- package/lib/narration.js +53 -0
- package/lib/pdf-structure.js +142 -0
- package/lib/preview-export.js +231 -0
- package/lib/preview-routes-api.js +662 -0
- package/lib/preview-routes-editing.js +159 -0
- package/lib/preview-routes-lms.js +230 -0
- package/lib/preview-server.js +564 -0
- package/lib/project-utils.js +269 -0
- package/lib/proxy-templates/proxy.html +68 -0
- package/lib/proxy-templates/scorm-bridge.js +112 -0
- package/lib/scaffold.js +193 -0
- package/lib/schema-extractor.js +361 -0
- package/lib/slide-source-editor.js +586 -0
- package/lib/stub-player/app-viewer.js +195 -0
- package/lib/stub-player/app.js +370 -0
- package/lib/stub-player/catalog-panel.js +312 -0
- package/lib/stub-player/config-panel.js +1303 -0
- package/lib/stub-player/content-generator.js +586 -0
- package/lib/stub-player/content-viewer.js +173 -0
- package/lib/stub-player/debug-panel.js +420 -0
- package/lib/stub-player/edit-mode.js +922 -0
- package/lib/stub-player/edit-utils.js +400 -0
- package/lib/stub-player/header-bar.js +354 -0
- package/lib/stub-player/interaction-editor.js +210 -0
- package/lib/stub-player/interactions-panel.js +565 -0
- package/lib/stub-player/lms-api.js +1094 -0
- package/lib/stub-player/login-screen.js +74 -0
- package/lib/stub-player/outline-mode.js +689 -0
- package/lib/stub-player/styles/_assessments-panel.css +245 -0
- package/lib/stub-player/styles/_base.css +89 -0
- package/lib/stub-player/styles/_catalog-icons.css +96 -0
- package/lib/stub-player/styles/_catalog-panel.css +291 -0
- package/lib/stub-player/styles/_config-panel.css +636 -0
- package/lib/stub-player/styles/_content-viewer.css +834 -0
- package/lib/stub-player/styles/_debug-panel.css +576 -0
- package/lib/stub-player/styles/_edit-mode.css +128 -0
- package/lib/stub-player/styles/_header-bar.css +343 -0
- package/lib/stub-player/styles/_interaction-editor.css +140 -0
- package/lib/stub-player/styles/_interactions-panel.css +1038 -0
- package/lib/stub-player/styles/_login-screen.css +102 -0
- package/lib/stub-player/styles/_outline-mode.css +752 -0
- package/lib/stub-player/styles.css +15 -0
- package/lib/stub-player.js +160 -0
- package/lib/test-data-reporting.js +176 -0
- package/lib/test-error-reporting.js +146 -0
- package/lib/token.js +86 -0
- package/lib/upgrade.js +257 -0
- package/lib/validation-rules.js +517 -0
- package/lib/vite-plugin-content-discovery.js +296 -0
- package/package.json +108 -0
- package/schemas/XMLSchema.dtd +402 -0
- package/schemas/adlcp_v1p3.xsd +111 -0
- package/schemas/adlnav_v1p3.xsd +61 -0
- package/schemas/adlseq_v1p3.xsd +93 -0
- package/schemas/common/anyElement.xsd +27 -0
- package/schemas/common/dataTypes.xsd +138 -0
- package/schemas/common/elementNames.xsd +767 -0
- package/schemas/common/elementTypes.xsd +786 -0
- package/schemas/common/rootElement.xsd +31 -0
- package/schemas/common/vocabTypes.xsd +345 -0
- package/schemas/common/vocabValues.xsd +257 -0
- package/schemas/datatypes.dtd +203 -0
- package/schemas/ims_xml.xsd +35 -0
- package/schemas/imscp_v1p1.xsd +368 -0
- package/schemas/imsss_v1p0.xsd +67 -0
- package/schemas/imsss_v1p0auxresource.xsd +19 -0
- package/schemas/imsss_v1p0control.xsd +20 -0
- package/schemas/imsss_v1p0delivery.xsd +17 -0
- package/schemas/imsss_v1p0limit.xsd +47 -0
- package/schemas/imsss_v1p0objective.xsd +67 -0
- package/schemas/imsss_v1p0random.xsd +16 -0
- package/schemas/imsss_v1p0rollup.xsd +46 -0
- package/schemas/imsss_v1p0seqrule.xsd +108 -0
- package/schemas/imsss_v1p0util.xsd +94 -0
- package/schemas/license.txt +17 -0
- package/schemas/lom.xsd +102 -0
- package/schemas/lomCustom.xsd +62 -0
- package/schemas/lomLoose.xsd +62 -0
- package/schemas/lomStrict.xsd +62 -0
- package/schemas/xml.xsd +81 -0
- package/template/.env.example +92 -0
- package/template/course/assets/audio/example-intro.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--compact-player.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--demo-modal.mp3 +0 -0
- package/template/course/assets/audio/example-ui-demo--full-player.mp3 +0 -0
- package/template/course/assets/docs/example_md_1.md +39 -0
- package/template/course/assets/docs/example_md_2.md +41 -0
- package/template/course/assets/docs/example_pdf_1_thumbnail.png +0 -0
- package/template/course/assets/docs/example_pdf_2.pdf +0 -0
- package/template/course/assets/images/course-architecture.svg +36 -0
- package/template/course/assets/images/logo.svg +14 -0
- package/template/course/assets/widgets/counter-demo.html +190 -0
- package/template/course/assets/widgets/gravity-painter.html +384 -0
- package/template/course/course-config.js +539 -0
- package/template/course/icons.js +19 -0
- package/template/course/interactions/PLUGIN_GUIDE.md +97 -0
- package/template/course/slides/example-course-structure.js +138 -0
- package/template/course/slides/example-final-exam.js +144 -0
- package/template/course/slides/example-finishing.js +127 -0
- package/template/course/slides/example-interactions-showcase.js +615 -0
- package/template/course/slides/example-preview-tour.js +129 -0
- package/template/course/slides/example-remedial.js +143 -0
- package/template/course/slides/example-summary.js +103 -0
- package/template/course/slides/example-ui-showcase.js +1805 -0
- package/template/course/slides/example-welcome.js +123 -0
- package/template/course/slides/example-workflow.js +140 -0
- package/template/course/theme.css +165 -0
- package/template/eslint.config.js +47 -0
- package/template/package.json +28 -0
- package/template/vite.config.js +339 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Seth Vincent
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# CourseCode
|
|
2
|
+
|
|
3
|
+
**A modern framework for building interactive e-learning courses with AI-assisted authoring.**
|
|
4
|
+
|
|
5
|
+
Drop in your existing PDFs, Word docs, or PowerPoints — AI converts them into complete, interactive courses. No vendor lock-in, no subscriptions. Your content, your code, deployed to any LMS.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🔌 **MCP integration**: AI connects directly to your course — previews, screenshots, linting, and testing without manual file sharing
|
|
10
|
+
- 🎓 **Full LMS integration**: SCORM 1.2, SCORM 2004, cmi5, and LTI with complete tracking records
|
|
11
|
+
- 🤖 **AI-ready authoring**: Structured guides and MCP tools for AI-assisted course development
|
|
12
|
+
- 🧩 **Rich UI components**: Images, video, accordions, tabs, and custom sandboxed HTML/JS embeds
|
|
13
|
+
- 🎯 **Rich interactions**: Multiple choice, drag-drop, fill-in-the-blank, matching, sequencing, and more
|
|
14
|
+
- ♿ **Fully accessible**: WCAG 2.1 AA compliant with dark mode, high contrast, and reduced motion
|
|
15
|
+
- 🔊 **TTS audio narration**: Built-in player with AI text-to-speech generation (ElevenLabs, Deepgram, Google, BYO API Key)
|
|
16
|
+
- 📊 **Smart tracking**: Engagement requirements, learning objectives, and progress persistence
|
|
17
|
+
- 🎨 **Themeable design**: CSS custom properties for easy brand customization
|
|
18
|
+
- 🔗 **Custom endpoints**: Optional webhooks for error reporting and learning record storage
|
|
19
|
+
- 📥 **Drop-in content conversion**: Feed existing PDFs, Word docs, or PowerPoint files to AI and get a complete, interactive course
|
|
20
|
+
- 🖥️ **Live preview**: Visual editing, status dashboard, config panels, catalog browser, and full LMS simulation with debug tools
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
### Required
|
|
27
|
+
|
|
28
|
+
Install [Node.js](https://nodejs.org/) (v18 or later), then run:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g coursecode
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Recommended
|
|
35
|
+
|
|
36
|
+
- A code or text editor — [VS Code](https://code.visualstudio.com/), [Cursor](https://cursor.com/), or similar
|
|
37
|
+
- An AI coding assistant with MCP support — [Claude Code](https://claude.ai/code), [Cursor](https://cursor.com/), [Windsurf](https://codeium.com/windsurf), etc.
|
|
38
|
+
- [GitHub Desktop](https://desktop.github.com/) for version control
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
|
|
46
|
+
# Create a new course project
|
|
47
|
+
coursecode create my-course
|
|
48
|
+
cd my-course
|
|
49
|
+
|
|
50
|
+
# Start the preview server
|
|
51
|
+
coursecode preview
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Open `http://localhost:4173` to view and edit your course.
|
|
55
|
+
|
|
56
|
+
The example course included with every new project is a complete guide to using CourseCode.
|
|
57
|
+
|
|
58
|
+
📖 **New to CourseCode?** Read the [User Guide](framework/docs/USER_GUIDE.md) for step-by-step instructions.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## MCP Integration
|
|
63
|
+
|
|
64
|
+
CourseCode includes a built-in [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server. When your AI tool supports MCP, it connects directly to your course project — no manual file sharing needed.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
coursecode mcp
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
With MCP, your AI can:
|
|
71
|
+
- **Preview and screenshot** slides to verify layout and design
|
|
72
|
+
- **Lint its own code** and catch errors automatically
|
|
73
|
+
- **Navigate and test** interactions directly
|
|
74
|
+
- **Browse the component catalog** to discover available UI elements
|
|
75
|
+
- **Read course state** including engagement, scoring, and LMS data
|
|
76
|
+
|
|
77
|
+
See the [User Guide](framework/docs/USER_GUIDE.md#mcp-model-context-protocol) for setup instructions.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## The Course Directory
|
|
82
|
+
|
|
83
|
+
All your course content lives in the `course/` folder:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
my-course/
|
|
87
|
+
├── course/ # ← Your content goes here
|
|
88
|
+
│ ├── course-config.js # Course structure, format, objectives, settings
|
|
89
|
+
│ ├── slides/ # Slide content files
|
|
90
|
+
│ │ ├── intro.js
|
|
91
|
+
│ │ ├── content-01.js
|
|
92
|
+
│ │ └── assessment.js
|
|
93
|
+
│ ├── assets/ # Images, audio, video
|
|
94
|
+
│ │ ├── images/
|
|
95
|
+
│ │ └── audio/
|
|
96
|
+
│ ├── theme.css # Brand customization
|
|
97
|
+
|
|
98
|
+
├── framework/ # Framework code (don't edit)
|
|
99
|
+
│ └── docs/ # Guides and templates
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Your Course
|
|
103
|
+
|
|
104
|
+
| Location | What's There |
|
|
105
|
+
|----------|--------------|
|
|
106
|
+
| `course/course-config.js` | Course settings — structure, objectives, navigation rules |
|
|
107
|
+
| `course/slides/` | Your slide content (one file per slide) |
|
|
108
|
+
| `course/theme.css` | Brand colors and typography |
|
|
109
|
+
| `course/assets/` | Images, audio, and video files |
|
|
110
|
+
|
|
111
|
+
### Key Documentation
|
|
112
|
+
|
|
113
|
+
All guides are in `framework/docs/`:
|
|
114
|
+
|
|
115
|
+
| Document | Audience | Purpose |
|
|
116
|
+
|----------|----------|---------|
|
|
117
|
+
| `README.md` | Humans | Project overview and getting started |
|
|
118
|
+
| `USER_GUIDE.md` | Humans | Complete guide — workflows, features, deployment |
|
|
119
|
+
| `COURSE_AUTHORING_GUIDE.md` | AI Agents | Slide authoring, interactions, CSS styling |
|
|
120
|
+
| `COURSE_OUTLINE_GUIDE.md` | AI Agents | How to write effective course outlines |
|
|
121
|
+
| `COURSE_OUTLINE_TEMPLATE.md` | AI Agents | Blank template to start an outline |
|
|
122
|
+
| `FRAMEWORK_GUIDE.md` | AI Agents | Framework internals (advanced) |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## AI-Driven Authoring Workflow
|
|
127
|
+
|
|
128
|
+
Four steps to go from source materials to a deployed course.
|
|
129
|
+
|
|
130
|
+
### Step 1: Convert Your Source Materials
|
|
131
|
+
|
|
132
|
+
Place existing content (PDFs, Word docs, PowerPoints) in `course/references/`, then run:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
coursecode convert
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Converts to markdown in `course/references/converted/`. Skip this step if starting from scratch.
|
|
139
|
+
|
|
140
|
+
### Step 2: Create Your Course Outline
|
|
141
|
+
|
|
142
|
+
Ask your AI to create a course outline based on your content.
|
|
143
|
+
|
|
144
|
+
- **With MCP**: The AI reads your references and outline template automatically
|
|
145
|
+
- **Without MCP**: Share your converted docs, `COURSE_OUTLINE_TEMPLATE.md`, and `COURSE_OUTLINE_GUIDE.md` with your AI
|
|
146
|
+
|
|
147
|
+
Review and refine the outline before building.
|
|
148
|
+
|
|
149
|
+
### Step 3: Build the Course
|
|
150
|
+
|
|
151
|
+
Ask your AI to build slides from your approved outline.
|
|
152
|
+
|
|
153
|
+
- **With MCP**: The AI reads all docs, lints its code, and screenshots slides to verify
|
|
154
|
+
- **Without MCP**: Share your outline and `COURSE_AUTHORING_GUIDE.md` with your AI
|
|
155
|
+
|
|
156
|
+
### Step 4: Preview, Iterate, and Deploy
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
coursecode preview
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The preview server provides:
|
|
163
|
+
- **Live reload**: Changes appear instantly
|
|
164
|
+
- **Visual editing**: Click elements to edit content directly
|
|
165
|
+
- **Status dashboard**: Course health, errors, and build status at a glance
|
|
166
|
+
- **Config panels**: Adjust settings, interactions, and assessments
|
|
167
|
+
- **Component catalog**: Browse available UI elements with live previews
|
|
168
|
+
- **Debug tools**: Inspect LMS state, test interactions, verify tracking
|
|
169
|
+
|
|
170
|
+
When ready, build and deploy:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
coursecode build
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This creates a ZIP package ready for upload to any LMS.
|
|
177
|
+
|
|
178
|
+
**Share for review:** Export a standalone preview for stakeholders:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
coursecode preview --export
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Deploy to GitHub Pages, Netlify, or any static host. Optional password protection keeps content secure.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## CLI Commands
|
|
189
|
+
|
|
190
|
+
| Command | Description |
|
|
191
|
+
|---------|-------------|
|
|
192
|
+
| `coursecode create <name>` | Create a new course project |
|
|
193
|
+
| `coursecode preview` | Preview your course locally |
|
|
194
|
+
| `coursecode build` | Build course package (ZIP for LMS upload) |
|
|
195
|
+
| `coursecode build --format scorm1.2` | Build for specific LMS format |
|
|
196
|
+
| `coursecode mcp` | Start the MCP server for AI integration |
|
|
197
|
+
| `coursecode narration` | Generate audio narration from text |
|
|
198
|
+
| `coursecode convert` | Convert PDFs, Word, PowerPoint to markdown |
|
|
199
|
+
| `coursecode upgrade` | Upgrade to latest version |
|
|
200
|
+
|
|
201
|
+
### Output Format Options
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
coursecode build --format cmi5 # cmi5/xAPI (default, recommended)
|
|
205
|
+
coursecode build --format scorm2004 # SCORM 2004 4th Edition
|
|
206
|
+
coursecode build --format scorm1.2 # SCORM 1.2 (widest LMS support)
|
|
207
|
+
coursecode build --format lti # LTI 1.3
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## UI Components
|
|
213
|
+
|
|
214
|
+
Build engaging slides with interactive elements. No coding required — your AI assistant handles the implementation.
|
|
215
|
+
|
|
216
|
+
### Media & Widgets
|
|
217
|
+
|
|
218
|
+
| Component | Description |
|
|
219
|
+
|-----------|-------------|
|
|
220
|
+
| Tabs | Switch between content panels |
|
|
221
|
+
| Accordion | Expandable/collapsible sections |
|
|
222
|
+
| Flip Cards | Reveal content on click |
|
|
223
|
+
| Carousel | Swipe through slides |
|
|
224
|
+
| Modal | Pop-up detail views |
|
|
225
|
+
| Interactive Timeline | Clickable timeline events |
|
|
226
|
+
| Interactive Image | Hotspots on images |
|
|
227
|
+
| Embed Frame | Sandboxed HTML/JS content |
|
|
228
|
+
| Audio Player | Narration with controls |
|
|
229
|
+
| Video Player | Native, YouTube, or Vimeo |
|
|
230
|
+
|
|
231
|
+
### Slide Templates
|
|
232
|
+
|
|
233
|
+
Pre-designed layouts for common slide types. Just tell your AI assistant what you need.
|
|
234
|
+
|
|
235
|
+
| Template | Use Case |
|
|
236
|
+
|----------|----------|
|
|
237
|
+
| Intro Cards | Overview slide with key points below |
|
|
238
|
+
| Steps | Sequential instructions (numbered) |
|
|
239
|
+
| Features | Highlight 3-4 key capabilities |
|
|
240
|
+
| Comparison | Side-by-side options |
|
|
241
|
+
| Stats | Metrics and numbers with impact |
|
|
242
|
+
| Content + Image | Text alongside diagrams |
|
|
243
|
+
| Hero | Full-width intro with call-to-action |
|
|
244
|
+
| Timeline | Chronological events |
|
|
245
|
+
| Quote | Testimonials and citations |
|
|
246
|
+
| Checklist | Task lists and requirements |
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Interaction Types
|
|
251
|
+
|
|
252
|
+
Practice activities that engage learners and check understanding.
|
|
253
|
+
|
|
254
|
+
| Type | Description |
|
|
255
|
+
|------|-------------|
|
|
256
|
+
| Multiple Choice | Select one or more correct answers |
|
|
257
|
+
| True/False | Simple yes/no questions |
|
|
258
|
+
| Fill-in-the-Blank | Enter missing text (supports typo tolerance) |
|
|
259
|
+
| Matching | Connect related items |
|
|
260
|
+
| Drag-and-Drop | Sort items into categories |
|
|
261
|
+
| Sequencing | Arrange items in correct order |
|
|
262
|
+
| Numeric | Enter numbers (exact or range) |
|
|
263
|
+
| Hotspot | Click correct areas on an image |
|
|
264
|
+
| Likert Scale | Rating scales for surveys |
|
|
265
|
+
|
|
266
|
+
All interactions provide immediate feedback and can be required for slide completion.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Tracking & Scoring
|
|
271
|
+
|
|
272
|
+
### Engagement
|
|
273
|
+
|
|
274
|
+
Require learners to complete activities before advancing:
|
|
275
|
+
- View all tabs or accordion panels
|
|
276
|
+
- Complete interactions
|
|
277
|
+
- Watch video or listen to audio
|
|
278
|
+
- Spend minimum time on slide
|
|
279
|
+
|
|
280
|
+
### Gating
|
|
281
|
+
|
|
282
|
+
Lock slides until conditions are met:
|
|
283
|
+
- Complete previous slides
|
|
284
|
+
- Pass an assessment
|
|
285
|
+
- Achieve a learning objective
|
|
286
|
+
|
|
287
|
+
### Assessments
|
|
288
|
+
|
|
289
|
+
Graded quizzes that determine course completion:
|
|
290
|
+
- Randomized question order
|
|
291
|
+
- Question banks for variety
|
|
292
|
+
- Configurable passing scores
|
|
293
|
+
- Retry attempts with remediation
|
|
294
|
+
- Scores reported to your LMS
|
|
295
|
+
|
|
296
|
+
### Learning Objectives
|
|
297
|
+
|
|
298
|
+
Track learner progress against defined goals:
|
|
299
|
+
- Automatic: track when slides are visited
|
|
300
|
+
- Linked: tie objectives to assessment scores
|
|
301
|
+
- Reported: completion status sent to LMS
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Learn More
|
|
306
|
+
|
|
307
|
+
The [User Guide](framework/docs/USER_GUIDE.md) covers everything in detail:
|
|
308
|
+
|
|
309
|
+
- Using the preview and visual editing tools
|
|
310
|
+
- All interaction types (multiple choice, drag-drop, matching, and more)
|
|
311
|
+
- Assessments and grading
|
|
312
|
+
- Audio and video
|
|
313
|
+
- Theming and branding
|
|
314
|
+
- Navigation and learner flow control
|
|
315
|
+
- Deployment options
|
|
316
|
+
- Troubleshooting
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## License
|
|
321
|
+
|
|
322
|
+
MIT © Seth Vincent
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Third-Party Notices
|
|
2
|
+
|
|
3
|
+
This project includes third-party components and standards artifacts.
|
|
4
|
+
|
|
5
|
+
## pipwerks SCORM Wrapper
|
|
6
|
+
|
|
7
|
+
- Path: `framework/js/vendor/pipwerks.js`
|
|
8
|
+
- Upstream: https://github.com/pipwerks/scorm-api-wrapper
|
|
9
|
+
- License: MIT-style (as stated in the file header)
|
|
10
|
+
|
|
11
|
+
## IEEE LOM / SCORM Schema Files
|
|
12
|
+
|
|
13
|
+
- Path: `schemas/` and `schemas/common/`
|
|
14
|
+
- Notes: Several schema files include embedded attribution text referencing
|
|
15
|
+
Creative Commons Attribution-ShareAlike.
|
|
16
|
+
- Local license reference file: `schemas/license.txt`
|
|
17
|
+
- License URL: https://creativecommons.org/licenses/by-sa/1.0/legalcode
|
|
18
|
+
|
|
19
|
+
## Project License
|
|
20
|
+
|
|
21
|
+
- This project’s primary license is MIT.
|
|
22
|
+
- See: `LICENSE`
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CourseCode CLI
|
|
5
|
+
*
|
|
6
|
+
* Commands:
|
|
7
|
+
* coursecode create <name> - Create a new course project
|
|
8
|
+
* coursecode dev - Start development server
|
|
9
|
+
* coursecode build - Build course package
|
|
10
|
+
* coursecode upgrade - Upgrade framework in current project
|
|
11
|
+
* coursecode clean - Remove example files from project
|
|
12
|
+
* coursecode new <type> - Create new slide, assessment, or config
|
|
13
|
+
* coursecode test-errors - Test error reporting configuration
|
|
14
|
+
* coursecode test-data - Test data reporting configuration
|
|
15
|
+
* coursecode --version - Show version
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { Command } from 'commander';
|
|
19
|
+
import { fileURLToPath } from 'url';
|
|
20
|
+
import path from 'path';
|
|
21
|
+
import fs from 'fs';
|
|
22
|
+
|
|
23
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
25
|
+
|
|
26
|
+
const program = new Command();
|
|
27
|
+
|
|
28
|
+
program
|
|
29
|
+
.name('coursecode')
|
|
30
|
+
.description('Multi-format course authoring framework CLI')
|
|
31
|
+
.version(packageJson.version);
|
|
32
|
+
|
|
33
|
+
// Create command
|
|
34
|
+
program
|
|
35
|
+
.command('create <name>')
|
|
36
|
+
.description('Create a new course project')
|
|
37
|
+
.option('--blank', 'Create without example slides (clean starter)')
|
|
38
|
+
.option('--no-install', 'Skip npm install')
|
|
39
|
+
.action(async (name, options) => {
|
|
40
|
+
const { create } = await import('../lib/create.js');
|
|
41
|
+
await create(name, options);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Dev command
|
|
45
|
+
program
|
|
46
|
+
.command('dev')
|
|
47
|
+
.description('Start development server with hot reload')
|
|
48
|
+
.option('-p, --port <port>', 'Port to run on', '5173')
|
|
49
|
+
.option('-f, --format <format>', 'LMS format: scorm2004, scorm1.2, cmi5, lti, scorm1.2-proxy, scorm2004-proxy, or cmi5-remote')
|
|
50
|
+
.action(async (options) => {
|
|
51
|
+
const { dev } = await import('../lib/dev.js');
|
|
52
|
+
await dev(options);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Build command
|
|
56
|
+
program
|
|
57
|
+
.command('build')
|
|
58
|
+
.description('Build course package for LMS deployment')
|
|
59
|
+
.option('--no-zip', 'Skip ZIP archive creation')
|
|
60
|
+
.option('--no-lint', 'Skip linting')
|
|
61
|
+
.option('-f, --format <format>', 'LMS format: scorm2004, scorm1.2, cmi5, lti, scorm1.2-proxy, scorm2004-proxy, or cmi5-remote')
|
|
62
|
+
.action(async (options) => {
|
|
63
|
+
const { build } = await import('../lib/build.js');
|
|
64
|
+
await build(options);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Lint command
|
|
68
|
+
program
|
|
69
|
+
.command('lint')
|
|
70
|
+
.description('Validate course configuration and structure')
|
|
71
|
+
.option('--course-path <path>', 'Path to course directory (default: ./course)', './course')
|
|
72
|
+
.option('-v, --verbose', 'Show detailed error output')
|
|
73
|
+
.action(async (options) => {
|
|
74
|
+
const { lint } = await import('../lib/build-linter.js');
|
|
75
|
+
await lint(options);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Upgrade command
|
|
79
|
+
program
|
|
80
|
+
.command('upgrade')
|
|
81
|
+
.description('Upgrade framework in current project to latest version')
|
|
82
|
+
.option('-f, --force', 'Force upgrade even if versions match')
|
|
83
|
+
.option('-c, --configs', 'Also update vite.config.js and eslint.config.js (creates backups)')
|
|
84
|
+
.option('--dry-run', 'Show what would be changed without making changes')
|
|
85
|
+
.action(async (options) => {
|
|
86
|
+
const { upgrade } = await import('../lib/upgrade.js');
|
|
87
|
+
await upgrade(options);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Narration command
|
|
91
|
+
program
|
|
92
|
+
.command('narration')
|
|
93
|
+
.description('Generate audio narration from text using ElevenLabs')
|
|
94
|
+
.option('-f, --force', 'Regenerate all narration (ignore cache)')
|
|
95
|
+
.option('-s, --slide <id>', 'Generate narration for a specific slide only')
|
|
96
|
+
.option('--dry-run', 'Preview what would be generated')
|
|
97
|
+
.action(async (options) => {
|
|
98
|
+
const { narration } = await import('../lib/narration.js');
|
|
99
|
+
await narration(options);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Export content command
|
|
103
|
+
program
|
|
104
|
+
.command('export-content')
|
|
105
|
+
.description('Export course content to Markdown or JSON for review/localization. Extracts: headers, tabs, accordions, callouts, cards, flip-cards, tables, pattern layouts, and all interaction types.')
|
|
106
|
+
.option('-o, --output <file>', 'Output file path (defaults to stdout)')
|
|
107
|
+
.option('--no-answers', 'Exclude correct answers for interactions (included by default)')
|
|
108
|
+
.option('--no-feedback', 'Exclude feedback text (included by default)')
|
|
109
|
+
.option('--no-interactions', 'Exclude interactions and assessment questions from output')
|
|
110
|
+
.option('--include-narration', 'Include narration transcripts')
|
|
111
|
+
.option('--interactions-only', 'Export only interactions and assessment questions (no slide content)')
|
|
112
|
+
.option('--slides <ids>', 'Comma-separated slide IDs to export')
|
|
113
|
+
.option('--format <type>', 'Output format: md or json (default: md)', 'md')
|
|
114
|
+
.option('--course-path <path>', 'Path to course directory (default: ./course)', './course')
|
|
115
|
+
.option('--include-anchors', 'Include HTML anchor tags for internal linking (used by preview content viewer)')
|
|
116
|
+
.action(async (options) => {
|
|
117
|
+
const { exportContent } = await import('../lib/export-content.js');
|
|
118
|
+
// Commander uses --no-X pattern: answers defaults to true, --no-answers sets it to false
|
|
119
|
+
const exportOptions = {
|
|
120
|
+
...options,
|
|
121
|
+
includeAnswers: options.answers !== false,
|
|
122
|
+
includeFeedback: options.feedback !== false,
|
|
123
|
+
excludeInteractions: options.interactions === false,
|
|
124
|
+
includeAnchors: options.includeAnchors === true ? true : undefined,
|
|
125
|
+
};
|
|
126
|
+
await exportContent(exportOptions);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Convert command
|
|
130
|
+
program
|
|
131
|
+
.command('convert [source]')
|
|
132
|
+
.description('Convert docx, pptx, and pdf files to markdown for course authoring')
|
|
133
|
+
.option('-o, --output <dir>', 'Output directory for converted files', './course/references/converted')
|
|
134
|
+
.option('-f, --format <type>', 'Limit to format: docx, pptx, pdf, or all', 'all')
|
|
135
|
+
.option('--dry-run', 'Show what would be converted without writing files')
|
|
136
|
+
.option('--overwrite', 'Overwrite existing markdown files')
|
|
137
|
+
.option('--flatten', 'Output all files to single directory (no subdirs)')
|
|
138
|
+
.action(async (source = './course/references', options) => {
|
|
139
|
+
const { convert } = await import('../lib/convert.js');
|
|
140
|
+
await convert(source, options);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Import command - PowerPoint to presentation course
|
|
144
|
+
program
|
|
145
|
+
.command('import <source>')
|
|
146
|
+
.description('Import a PowerPoint file as a presentation course')
|
|
147
|
+
.option('-n, --name <name>', 'Project name (default: derived from filename)')
|
|
148
|
+
.option('--slides-dir <dir>', 'Use pre-exported slide images from this directory (skips PowerPoint)')
|
|
149
|
+
.option('--no-install', 'Skip npm install')
|
|
150
|
+
.action(async (source, options) => {
|
|
151
|
+
const { importPresentation } = await import('../lib/import.js');
|
|
152
|
+
await importPresentation(source, options);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Preview command - live preview with stub LMS, or export static preview
|
|
156
|
+
program
|
|
157
|
+
.command('preview')
|
|
158
|
+
.description('Live preview with stub LMS + auto-rebuild, or export static preview')
|
|
159
|
+
.option('-e, --export', 'Export static preview folder for sharing (instead of live server)')
|
|
160
|
+
.option('-o, --output <dir>', 'Output directory for export (default: ./course-preview)', './course-preview')
|
|
161
|
+
.option('-p, --password <password>', 'Require password to access preview (export only)')
|
|
162
|
+
.option('--title <title>', 'Custom title (default: course title)')
|
|
163
|
+
.option('--port <port>', 'Preview server port (default: 4173)', '4173')
|
|
164
|
+
.option('--skip-build', 'Skip build step for export (use existing dist folder)')
|
|
165
|
+
.option('--nojekyll', 'Add .nojekyll file (required for GitHub Pages)')
|
|
166
|
+
.option('--no-content', 'Exclude course content viewer from preview toolbar')
|
|
167
|
+
.option('-f, --format <format>', 'LMS format: scorm2004, scorm1.2, cmi5, lti, scorm1.2-proxy, scorm2004-proxy, or cmi5-remote')
|
|
168
|
+
.option('--desktop', 'Signal that preview is launched via the desktop companion app')
|
|
169
|
+
.action(async (options) => {
|
|
170
|
+
if (options.export) {
|
|
171
|
+
const { previewExport } = await import('../lib/preview-export.js');
|
|
172
|
+
await previewExport(options);
|
|
173
|
+
} else {
|
|
174
|
+
const { previewServer } = await import('../lib/preview-server.js');
|
|
175
|
+
await previewServer(options);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Info command (useful for debugging)
|
|
180
|
+
program
|
|
181
|
+
.command('info')
|
|
182
|
+
.description('Show info about current project')
|
|
183
|
+
.action(async () => {
|
|
184
|
+
const { info } = await import('../lib/info.js');
|
|
185
|
+
await info();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Test error reporting command
|
|
189
|
+
program
|
|
190
|
+
.command('test-errors')
|
|
191
|
+
.description('Send a test error to verify error reporting is configured correctly')
|
|
192
|
+
.option('-t, --type <type>', 'Type of test: error or report', 'error')
|
|
193
|
+
.option('-m, --message <message>', 'Custom message to include in the test')
|
|
194
|
+
.option('--insecure', 'Skip TLS certificate verification (for corporate proxies)')
|
|
195
|
+
.action(async (options) => {
|
|
196
|
+
const { testErrorReporting } = await import('../lib/test-error-reporting.js');
|
|
197
|
+
await testErrorReporting(options);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Test data reporting command
|
|
201
|
+
program
|
|
202
|
+
.command('test-data')
|
|
203
|
+
.description('Send a test data record to verify data reporting is configured correctly')
|
|
204
|
+
.option('-t, --type <type>', 'Type of record: assessment, objective, or interaction', 'assessment')
|
|
205
|
+
.option('-m, --message <message>', 'Custom message to include in the test')
|
|
206
|
+
.option('--insecure', 'Skip TLS certificate verification (for corporate proxies)')
|
|
207
|
+
.action(async (options) => {
|
|
208
|
+
const { testDataReporting } = await import('../lib/test-data-reporting.js');
|
|
209
|
+
await testDataReporting(options);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// MCP server command
|
|
213
|
+
program
|
|
214
|
+
.command('mcp')
|
|
215
|
+
.description('Start MCP server for AI agent integration (connects to running preview server)')
|
|
216
|
+
.option('--port <port>', 'Preview server port to connect to', '4173')
|
|
217
|
+
.action(async (options) => {
|
|
218
|
+
const { startMcpServer } = await import('../lib/mcp-server.js');
|
|
219
|
+
await startMcpServer(options);
|
|
220
|
+
});
|
|
221
|
+
// Token generation command
|
|
222
|
+
program
|
|
223
|
+
.command('token')
|
|
224
|
+
.description('Generate access token for multi-tenant CDN deployment')
|
|
225
|
+
.option('--add <clientId>', 'Add client to course-config with generated token')
|
|
226
|
+
.action(async (options) => {
|
|
227
|
+
const { token } = await import('../lib/token.js');
|
|
228
|
+
await token(options);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Clean command - remove example files from project
|
|
232
|
+
program
|
|
233
|
+
.command('clean')
|
|
234
|
+
.description('Remove example slides, audio, and reset course-config.js to minimal starter')
|
|
235
|
+
.action(async () => {
|
|
236
|
+
const { clean } = await import('../lib/scaffold.js');
|
|
237
|
+
clean();
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// New command - scaffold new files
|
|
241
|
+
const newCmd = program
|
|
242
|
+
.command('new')
|
|
243
|
+
.description('Create new course files (slide, assessment, or config)');
|
|
244
|
+
|
|
245
|
+
newCmd
|
|
246
|
+
.command('slide <id>')
|
|
247
|
+
.description('Create a new slide file in course/slides/')
|
|
248
|
+
.action(async (id) => {
|
|
249
|
+
const { newSlide } = await import('../lib/scaffold.js');
|
|
250
|
+
newSlide(id);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
newCmd
|
|
254
|
+
.command('assessment <id>')
|
|
255
|
+
.description('Create a new assessment file in course/slides/')
|
|
256
|
+
.action(async (id) => {
|
|
257
|
+
const { newAssessment } = await import('../lib/scaffold.js');
|
|
258
|
+
newAssessment(id);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
newCmd
|
|
262
|
+
.command('config')
|
|
263
|
+
.description('Create a minimal course-config.js (errors if one exists)')
|
|
264
|
+
.action(async () => {
|
|
265
|
+
const { newConfig } = await import('../lib/scaffold.js');
|
|
266
|
+
newConfig();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// Cloud commands — all support --local to target http://localhost:3000
|
|
270
|
+
program
|
|
271
|
+
.command('login')
|
|
272
|
+
.description('Log in to CourseCode Cloud')
|
|
273
|
+
.option('--local', 'Use local Cloud instance (http://localhost:3000)')
|
|
274
|
+
.action(async (options) => {
|
|
275
|
+
const { login, setLocalMode } = await import('../lib/cloud.js');
|
|
276
|
+
if (options.local) setLocalMode();
|
|
277
|
+
await login();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
program
|
|
281
|
+
.command('logout')
|
|
282
|
+
.description('Log out of CourseCode Cloud')
|
|
283
|
+
.action(async () => {
|
|
284
|
+
const { logout } = await import('../lib/cloud.js');
|
|
285
|
+
await logout();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
program
|
|
289
|
+
.command('whoami')
|
|
290
|
+
.description('Show current Cloud user and organizations')
|
|
291
|
+
.option('--local', 'Use local Cloud instance (http://localhost:3000)')
|
|
292
|
+
.option('--json', 'Output raw JSON')
|
|
293
|
+
.action(async (options) => {
|
|
294
|
+
const { whoami, setLocalMode } = await import('../lib/cloud.js');
|
|
295
|
+
if (options.local) setLocalMode();
|
|
296
|
+
await whoami({ json: options.json });
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
program
|
|
300
|
+
.command('courses')
|
|
301
|
+
.description('List courses on CourseCode Cloud')
|
|
302
|
+
.option('--local', 'Use local Cloud instance (http://localhost:3000)')
|
|
303
|
+
.action(async (options) => {
|
|
304
|
+
const { listCourses, setLocalMode } = await import('../lib/cloud.js');
|
|
305
|
+
if (options.local) setLocalMode();
|
|
306
|
+
await listCourses();
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
program
|
|
310
|
+
.command('deploy')
|
|
311
|
+
.description('Build and deploy course to CourseCode Cloud')
|
|
312
|
+
.option('--preview', 'Deploy as preview (expires in 7 days)')
|
|
313
|
+
.option('--password', 'Password-protect preview (interactive prompt)')
|
|
314
|
+
.option('--local', 'Use local Cloud instance (http://localhost:3000)')
|
|
315
|
+
.action(async (options) => {
|
|
316
|
+
const { deploy, setLocalMode } = await import('../lib/cloud.js');
|
|
317
|
+
if (options.local) setLocalMode();
|
|
318
|
+
await deploy(options);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
program
|
|
322
|
+
.command('status')
|
|
323
|
+
.description('Show deployment status for current course')
|
|
324
|
+
.option('--local', 'Use local Cloud instance (http://localhost:3000)')
|
|
325
|
+
.action(async (options) => {
|
|
326
|
+
const { status, setLocalMode } = await import('../lib/cloud.js');
|
|
327
|
+
if (options.local) setLocalMode();
|
|
328
|
+
await status();
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
program.parse();
|