coursecode 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -6,18 +6,20 @@ Drop in your existing PDFs, Word docs, or PowerPoints — AI converts them into
6
6
 
7
7
  ## Features
8
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
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
+ - **[CourseCode Cloud](https://www.coursecodecloud.com)** *(coming soon)*: Deploy from CLI, share preview links, download any LMS format on demand — no rebuilds
22
+ - **CourseCode Desktop** *(coming soon)*: Native app for Mac and Windows with AI-assisted editing, built-in preview, and no code required
21
23
 
22
24
  ---
23
25
 
@@ -55,7 +57,7 @@ Open `http://localhost:4173` to view and edit your course.
55
57
 
56
58
  The example course included with every new project is a complete guide to using CourseCode.
57
59
 
58
- 📖 **New to CourseCode?** Read the [User Guide](framework/docs/USER_GUIDE.md) for step-by-step instructions.
60
+ **New to CourseCode?** Read the [User Guide](framework/docs/USER_GUIDE.md) for step-by-step instructions.
59
61
 
60
62
  ---
61
63
 
@@ -93,8 +95,8 @@ my-course/
93
95
  │ ├── assets/ # Images, audio, video
94
96
  │ │ ├── images/
95
97
  │ │ └── audio/
96
- ├── theme.css # Brand customization
97
-
98
+ └── theme.css # Brand customization
99
+
98
100
  ├── framework/ # Framework code (don't edit)
99
101
  │ └── docs/ # Guides and templates
100
102
  ```
@@ -114,11 +116,11 @@ All guides are in `framework/docs/`:
114
116
 
115
117
  | Document | Audience | Purpose |
116
118
  |----------|----------|---------|
117
- | `README.md` | Humans | Project overview and getting started |
118
119
  | `USER_GUIDE.md` | Humans | Complete guide — workflows, features, deployment |
119
120
  | `COURSE_AUTHORING_GUIDE.md` | AI Agents | Slide authoring, interactions, CSS styling |
120
121
  | `COURSE_OUTLINE_GUIDE.md` | AI Agents | How to write effective course outlines |
121
122
  | `COURSE_OUTLINE_TEMPLATE.md` | AI Agents | Blank template to start an outline |
123
+ | `DATA_MODEL.md` | AI Agents | LMS data model and tracking fields |
122
124
  | `FRAMEWORK_GUIDE.md` | AI Agents | Framework internals (advanced) |
123
125
 
124
126
  ---
@@ -167,22 +169,26 @@ The preview server provides:
167
169
  - **Component catalog**: Browse available UI elements with live previews
168
170
  - **Debug tools**: Inspect LMS state, test interactions, verify tracking
169
171
 
170
- When ready, build and deploy:
172
+ When ready, deploy:
173
+
174
+ **With [CourseCode Cloud](https://www.coursecodecloud.com)** *(coming soon)*: Push your course and get a live link. Cloud handles hosting, generates any LMS format on demand, and gives you sharable preview links with optional password protection. No ZIP files, no manual uploads.
171
175
 
172
176
  ```bash
173
- coursecode build
177
+ coursecode deploy
174
178
  ```
175
179
 
176
- This creates a ZIP package ready for upload to any LMS.
180
+ **Without Cloud**: Build a ZIP package and upload it to your LMS manually:
181
+
182
+ ```bash
183
+ coursecode build
184
+ ```
177
185
 
178
- **Share for review:** Export a standalone preview for stakeholders:
186
+ **Share for review**: Export a standalone preview for stakeholders. Deploy to GitHub Pages, Netlify, or any static host:
179
187
 
180
188
  ```bash
181
189
  coursecode preview --export
182
190
  ```
183
191
 
184
- Deploy to GitHub Pages, Netlify, or any static host. Optional password protection keeps content secure.
185
-
186
192
  ---
187
193
 
188
194
  ## CLI Commands
@@ -194,10 +200,22 @@ Deploy to GitHub Pages, Netlify, or any static host. Optional password protectio
194
200
  | `coursecode build` | Build course package (ZIP for LMS upload) |
195
201
  | `coursecode build --format scorm1.2` | Build for specific LMS format |
196
202
  | `coursecode mcp` | Start the MCP server for AI integration |
203
+ | `coursecode lint` | Validate course configuration and structure |
197
204
  | `coursecode narration` | Generate audio narration from text |
198
205
  | `coursecode convert` | Convert PDFs, Word, PowerPoint to markdown |
199
206
  | `coursecode upgrade` | Upgrade to latest version |
200
207
 
208
+ ### Cloud Commands
209
+
210
+ | Command | Description |
211
+ |---------|-------------|
212
+ | `coursecode login` | Log in to CourseCode Cloud |
213
+ | `coursecode logout` | Log out of CourseCode Cloud |
214
+ | `coursecode whoami` | Show current Cloud user and organizations |
215
+ | `coursecode courses` | List courses on CourseCode Cloud |
216
+ | `coursecode deploy` | Build and deploy to CourseCode Cloud |
217
+ | `coursecode status` | Show deployment status for current course |
218
+
201
219
  ### Output Format Options
202
220
 
203
221
  ```bash
@@ -130,18 +130,17 @@ The ZIP never includes preview/stub player assets. Preview is a separate concern
130
130
 
131
131
  #### Re-Stamping for Different Formats
132
132
 
133
- `lib/build-packaging.js` exports `stampFormatInHtml(htmlPath, format)` for re-stamping the meta tag:
133
+ `lib/build-packaging.js` exports `stampFormat(html, format)` for re-stamping the meta tag:
134
134
 
135
135
  ```javascript
136
- import { stampFormatInHtml } from 'coursecode/build-packaging';
136
+ import { stampFormat } from 'coursecode/build-packaging';
137
137
  import { generateManifest } from 'coursecode/manifest';
138
138
 
139
- // Re-stamp dist/index.html for a different format
140
- stampFormatInHtml('/path/to/dist/index.html', 'scorm2004');
139
+ // Re-stamp HTML string for a different format (no filesystem needed)
140
+ const stampedHtml = stampFormat(indexHtml, 'scorm2004');
141
141
 
142
142
  // Generate the format-specific manifest
143
143
  const { filename, content } = generateManifest('scorm2004', config, files, options);
144
- fs.writeFileSync(`/path/to/dist/${filename}`, content);
145
144
  ```
146
145
 
147
146
  Both are pure Node utilities
@@ -152,7 +151,7 @@ Both are pure Node utilities
152
151
  |------|---------|
153
152
  | `framework/js/state/lms-connection.js` | `getLMSFormat()` — runtime priority chain (meta → env → default) |
154
153
  | `framework/js/drivers/driver-factory.js` | Dynamic `import()` switch — loads one driver at runtime |
155
- | `lib/build-packaging.js` | `stampFormatInHtml()` — meta tag re-stamping utility |
154
+ | `lib/build-packaging.js` | `stampFormat()` — pure string meta tag re-stamping; `stampFormatInHtml()` — file-based wrapper |
156
155
  | `lib/manifest/manifest-factory.js` | `generateManifest()` — generates format-specific manifests |
157
156
  | Both `vite.config.js` files | Post-build `closeBundle` hook stamps meta tag into `dist/index.html` |
158
157
 
@@ -586,7 +585,7 @@ User: coursecode build → uploads dist/
586
585
  └────────────┘
587
586
  ```
588
587
 
589
- **Cloud dependencies:** The cloud app imports `stampFormatInHtml` and `generateManifest` directly from the `coursecode` npm package. These are pure Node utilities — no Vite, no dynamic imports of user code, no `eval`. All inputs (title, version, file list) come from scanning the uploaded `dist/` or the cloud's own database.
588
+ **Cloud dependencies:** The cloud app imports `stampFormat` and `generateManifest` directly from the `coursecode` npm package. These are pure functions — no filesystem, no Vite, no dynamic imports of user code, no `eval`. All inputs (title, version, file list) come from scanning the uploaded `dist/` or the cloud's own database.
590
589
 
591
590
  **Security boundary:** The cloud never executes `course-config.js` or any user-authored JavaScript. The meta tag and manifest are the only format-specific artifacts, and both are generated from trusted framework source code.
592
591
  ---
@@ -0,0 +1,33 @@
1
+ export function stampFormat(html: string, format: string): string
2
+ export function stampFormatInHtml(htmlPath: string, format: string): void
3
+
4
+ export function validateExternalHostingConfig(config: Record<string, unknown>): void
5
+
6
+ export function createStandardPackage(options: {
7
+ rootDir: string
8
+ distDir: string
9
+ config: Record<string, unknown>
10
+ outputDir?: string
11
+ }): Promise<string>
12
+
13
+ export function createProxyPackage(options: {
14
+ rootDir: string
15
+ config: Record<string, unknown>
16
+ clientId?: string
17
+ token?: string
18
+ outputDir?: string
19
+ }): Promise<string>
20
+
21
+ export function createRemotePackage(options: {
22
+ rootDir: string
23
+ config: Record<string, unknown>
24
+ clientId?: string
25
+ token?: string
26
+ outputDir?: string
27
+ }): Promise<string>
28
+
29
+ export function createExternalPackagesForClients(options: {
30
+ rootDir: string
31
+ config: Record<string, unknown>
32
+ outputDir?: string
33
+ }): Promise<void>
@@ -61,24 +61,31 @@ export function validateExternalHostingConfig(config) {
61
61
  }
62
62
 
63
63
  /**
64
- * Re-stamp the lms-format meta tag in an index.html file.
65
- * Used when creating format-specific ZIPs from a universal dist/.
66
- * @param {string} htmlPath - Absolute path to the index.html to modify
64
+ * Re-stamp the lms-format meta tag in an HTML string.
65
+ * Pure string transform no filesystem access. Use this in cloud/serverless environments.
66
+ * @param {string} html - The HTML string to modify
67
67
  * @param {string} format - The LMS format to stamp (e.g., 'scorm2004', 'cmi5')
68
+ * @returns {string} The modified HTML string
68
69
  */
69
- export function stampFormatInHtml(htmlPath, format) {
70
- let html = fs.readFileSync(htmlPath, 'utf-8');
71
- // Replace existing meta tag or insert after charset
70
+ export function stampFormat(html, format) {
72
71
  const existingMeta = /<meta\s+name="lms-format"\s+content="[^"]*"\s*\/?>/;
73
72
  if (existingMeta.test(html)) {
74
- html = html.replace(existingMeta, `<meta name="lms-format" content="${format}" />`);
75
- } else {
76
- html = html.replace(
77
- '<meta charset="UTF-8" />',
78
- `<meta charset="UTF-8" />\n <meta name="lms-format" content="${format}" />`
79
- );
73
+ return html.replace(existingMeta, `<meta name="lms-format" content="${format}" />`);
80
74
  }
81
- fs.writeFileSync(htmlPath, html, 'utf-8');
75
+ return html.replace(
76
+ '<meta charset="UTF-8" />',
77
+ `<meta charset="UTF-8" />\n <meta name="lms-format" content="${format}" />`
78
+ );
79
+ }
80
+
81
+ /**
82
+ * Re-stamp the lms-format meta tag in an index.html file on disk.
83
+ * @param {string} htmlPath - Absolute path to the index.html to modify
84
+ * @param {string} format - The LMS format to stamp (e.g., 'scorm2004', 'cmi5')
85
+ */
86
+ export function stampFormatInHtml(htmlPath, format) {
87
+ const html = fs.readFileSync(htmlPath, 'utf-8');
88
+ fs.writeFileSync(htmlPath, stampFormat(html, format), 'utf-8');
82
89
  }
83
90
 
84
91
  export async function createStandardPackage({ rootDir, distDir, config, outputDir }) {
package/lib/index.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ // Stub Player
2
+ export { generateStubPlayer } from './stub-player.js'
3
+ export type { StubPlayerConfig } from './stub-player.js'
4
+
5
+ // Manifest Generation
6
+ export function generateManifest(
7
+ format: string,
8
+ config: Record<string, unknown>,
9
+ files: string[],
10
+ options?: Record<string, unknown>
11
+ ): { filename: string; content: string }
12
+
13
+ export function getSchemaFiles(format: string): string[]
14
+
15
+ // Content Parsing
16
+ export function parseCourse(coursePath: string): Promise<Record<string, unknown>>
17
+ export function parseSlideSource(source: string, slideId: string): Record<string, unknown>
18
+ export function extractAssessment(source: string, slideId: string): Record<string, unknown> | null
19
+ export function extractNarration(source: string): Record<string, unknown> | null
20
+ export function extractInteractions(content: string, slideId: string): Record<string, unknown>[]
21
+ export function parseElements(html: string): Record<string, unknown>[]
22
+ export function resolveElementByPath(elements: Record<string, unknown>[], targetPath: string): Record<string, unknown> | null
23
+
24
+ // Build
25
+ export function build(options?: Record<string, unknown>): Promise<void>
26
+
27
+ // Build Packaging
28
+ export function stampFormat(html: string, format: string): string
29
+ export function stampFormatInHtml(htmlPath: string, format: string): void
30
+ export function validateExternalHostingConfig(config: Record<string, unknown>): void
31
+ export function createStandardPackage(options: Record<string, unknown>): Promise<string>
32
+ export function createProxyPackage(options: Record<string, unknown>): Promise<string>
33
+ export function createRemotePackage(options: Record<string, unknown>): Promise<string>
34
+ export function createExternalPackagesForClients(options: Record<string, unknown>): Promise<void>
35
+
36
+ // Build Linter
37
+ export function lintCourse(courseConfig: Record<string, unknown>, coursePath: string): { errors: string[]; warnings: string[] }
38
+ export function lint(options?: Record<string, unknown>): Promise<void>
39
+
40
+ // Validation Rules
41
+ export function flattenStructure(structure: unknown[]): unknown[]
42
+ export function validateAssessmentConfig(...args: unknown[]): void
43
+ export function validateQuestionConfig(...args: unknown[]): void
44
+ export function validateEngagement(...args: unknown[]): void
45
+ export function validateRequirementConfig(...args: unknown[]): void
46
+ export function validateGlobalConfig(...args: unknown[]): { warnings: string[]; objectiveIds: Set<string> }
47
+ export function formatLintResults(results: { errors: string[]; warnings: string[] }): string
48
+
49
+ // Path utilities
50
+ export function getTemplatePath(): string
51
+ export function getFrameworkPath(): string
52
+ export function getSchemasPath(): string
package/lib/index.js CHANGED
@@ -24,6 +24,7 @@ export {
24
24
  // Build utilities
25
25
  export { build } from './build.js';
26
26
  export {
27
+ stampFormat,
27
28
  createStandardPackage,
28
29
  createProxyPackage,
29
30
  createRemotePackage,
@@ -0,0 +1,10 @@
1
+ export function generateManifest(
2
+ format: 'scorm2004' | 'scorm1.2' | 'cmi5' | 'scorm1.2-proxy' | 'scorm2004-proxy' | 'cmi5-remote' | 'lti',
3
+ config: Record<string, unknown>,
4
+ files: string[],
5
+ options?: { externalUrl?: string }
6
+ ): { filename: string; content: string }
7
+
8
+ export function getSchemaFiles(
9
+ format: 'scorm2004' | 'scorm1.2' | 'cmi5' | 'lti'
10
+ ): string[]
@@ -0,0 +1,15 @@
1
+ export interface StubPlayerConfig {
2
+ title: string
3
+ launchUrl: string
4
+ storageKey: string
5
+ passwordHash?: string
6
+ isLive?: boolean
7
+ liveReload?: boolean
8
+ courseContent?: string
9
+ startSlide?: string | number
10
+ isDesktop?: boolean
11
+ moduleBasePath?: string
12
+ }
13
+
14
+ export function generateStubPlayer(config: StubPlayerConfig): string
15
+ export function escapeHtml(str: string): string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coursecode",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Multi-format course authoring framework with CLI tools (SCORM 2004, SCORM 1.2, cmi5, LTI 1.3)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,12 +20,22 @@
20
20
  "THIRD_PARTY_NOTICES.md"
21
21
  ],
22
22
  "exports": {
23
- ".": "./lib/index.js",
24
- "./manifest": "./lib/manifest/manifest-factory.js",
25
- "./build-packaging": "./lib/build-packaging.js",
26
- "./stub-player": "./lib/stub-player.js",
27
- "./course-parser": "./lib/course-parser.js",
28
- "./vite-plugin-content-discovery": "./lib/vite-plugin-content-discovery.js"
23
+ ".": {
24
+ "types": "./lib/index.d.ts",
25
+ "default": "./lib/index.js"
26
+ },
27
+ "./manifest": {
28
+ "types": "./lib/manifest/manifest-factory.d.ts",
29
+ "default": "./lib/manifest/manifest-factory.js"
30
+ },
31
+ "./build-packaging": {
32
+ "types": "./lib/build-packaging.d.ts",
33
+ "default": "./lib/build-packaging.js"
34
+ },
35
+ "./stub-player": {
36
+ "types": "./lib/stub-player.d.ts",
37
+ "default": "./lib/stub-player.js"
38
+ }
29
39
  },
30
40
  "scripts": {
31
41
  "dev": "VITE_COURSECODE_LOCAL=true npx vite build --config vite.framework-dev.config.js --mode development --watch",