@thanh01.pmt/curriculum-kit 1.0.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.
Files changed (68) hide show
  1. package/README.md +22 -0
  2. package/dist/ai/index.cjs +4980 -0
  3. package/dist/ai/index.cjs.map +1 -0
  4. package/dist/ai/index.d.cts +1287 -0
  5. package/dist/ai/index.d.ts +1287 -0
  6. package/dist/ai/index.mjs +4924 -0
  7. package/dist/ai/index.mjs.map +1 -0
  8. package/dist/index.cjs +15308 -0
  9. package/dist/index.cjs.map +1 -0
  10. package/dist/index.d.cts +747 -0
  11. package/dist/index.d.ts +747 -0
  12. package/dist/index.mjs +14965 -0
  13. package/dist/index.mjs.map +1 -0
  14. package/dist/media/index.cjs +1238 -0
  15. package/dist/media/index.cjs.map +1 -0
  16. package/dist/media/index.d.cts +254 -0
  17. package/dist/media/index.d.ts +254 -0
  18. package/dist/media/index.mjs +1221 -0
  19. package/dist/media/index.mjs.map +1 -0
  20. package/dist/milestoneBundleGenerator-CbXhs1CP.d.ts +62 -0
  21. package/dist/milestoneBundleGenerator-DrBtHzBO.d.cts +62 -0
  22. package/dist/pipeline/index.cjs +4894 -0
  23. package/dist/pipeline/index.cjs.map +1 -0
  24. package/dist/pipeline/index.d.cts +161 -0
  25. package/dist/pipeline/index.d.ts +161 -0
  26. package/dist/pipeline/index.mjs +4869 -0
  27. package/dist/pipeline/index.mjs.map +1 -0
  28. package/dist/provider-factory-DH3udYlN.d.cts +25 -0
  29. package/dist/provider-factory-DH3udYlN.d.ts +25 -0
  30. package/dist/publishers/index.cjs +575 -0
  31. package/dist/publishers/index.cjs.map +1 -0
  32. package/dist/publishers/index.d.cts +85 -0
  33. package/dist/publishers/index.d.ts +85 -0
  34. package/dist/publishers/index.mjs +561 -0
  35. package/dist/publishers/index.mjs.map +1 -0
  36. package/dist/schemas/index.cjs +1640 -0
  37. package/dist/schemas/index.cjs.map +1 -0
  38. package/dist/schemas/index.d.cts +14194 -0
  39. package/dist/schemas/index.d.ts +14194 -0
  40. package/dist/schemas/index.mjs +1517 -0
  41. package/dist/schemas/index.mjs.map +1 -0
  42. package/dist/standards/index.cjs +910 -0
  43. package/dist/standards/index.cjs.map +1 -0
  44. package/dist/standards/index.d.cts +130 -0
  45. package/dist/standards/index.d.ts +130 -0
  46. package/dist/standards/index.mjs +890 -0
  47. package/dist/standards/index.mjs.map +1 -0
  48. package/dist/standardsCoverageGate-BWAkXY76.d.cts +767 -0
  49. package/dist/standardsCoverageGate-BWAkXY76.d.ts +767 -0
  50. package/dist/storage/index.cjs +595 -0
  51. package/dist/storage/index.cjs.map +1 -0
  52. package/dist/storage/index.d.cts +77 -0
  53. package/dist/storage/index.d.ts +77 -0
  54. package/dist/storage/index.mjs +583 -0
  55. package/dist/storage/index.mjs.map +1 -0
  56. package/dist/streamRunner-C7j5LKon.d.cts +60 -0
  57. package/dist/streamRunner-C7j5LKon.d.ts +60 -0
  58. package/dist/supabasePublisher-C627qXFT.d.cts +63 -0
  59. package/dist/supabasePublisher-C627qXFT.d.ts +63 -0
  60. package/dist/types-BUJGYiep.d.cts +89 -0
  61. package/dist/types-BUJGYiep.d.ts +89 -0
  62. package/dist/workflow/index.cjs +5266 -0
  63. package/dist/workflow/index.cjs.map +1 -0
  64. package/dist/workflow/index.d.cts +295 -0
  65. package/dist/workflow/index.d.ts +295 -0
  66. package/dist/workflow/index.mjs +5216 -0
  67. package/dist/workflow/index.mjs.map +1 -0
  68. package/package.json +105 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/publishers/localWorkspaceManager.ts","../../src/publishers/gitPublisher.ts","../../src/publishers/supabasePublisher.ts","../../src/publishers/packagingService.ts"],"names":["fs","path","header","rows"],"mappings":"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","file":"index.mjs","sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface JobManifest {\n jobId: string;\n courseTitle: string;\n topic: string;\n language: string;\n status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';\n totalMilestones: number;\n completedMilestones: number;\n createdAt: string;\n updatedAt: string;\n artifacts: Array<{\n milestoneId: string;\n artifactType: string;\n filePath: string;\n sizeBytes: number;\n createdAt: string;\n }>;\n error?: string;\n}\n\nexport class LocalWorkspaceManager {\n private baseDir: string;\n\n constructor(baseDir?: string) {\n this.baseDir = baseDir || path.resolve(process.cwd(), 'output', 'workspace-jobs');\n }\n\n getJobDirectory(jobId: string): string {\n return path.join(this.baseDir, jobId);\n }\n\n async initJobWorkspace(\n jobId: string,\n initialInfo: { courseTitle: string; topic: string; language: string; totalMilestones: number }\n ): Promise<string> {\n const jobDir = this.getJobDirectory(jobId);\n await fs.mkdir(jobDir, { recursive: true });\n\n const now = new Date().toISOString();\n const manifest: JobManifest = {\n jobId,\n courseTitle: initialInfo.courseTitle,\n topic: initialInfo.topic,\n language: initialInfo.language,\n status: 'IN_PROGRESS',\n totalMilestones: initialInfo.totalMilestones,\n completedMilestones: 0,\n createdAt: now,\n updatedAt: now,\n artifacts: [],\n };\n\n await this.saveManifest(jobId, manifest);\n return jobDir;\n }\n\n async saveArtifact(\n jobId: string,\n milestoneSlug: string,\n filename: string,\n content: string,\n artifactType: string\n ): Promise<string> {\n const jobDir = this.getJobDirectory(jobId);\n const targetDir = path.join(jobDir, milestoneSlug);\n await fs.mkdir(targetDir, { recursive: true });\n\n const filePath = path.join(targetDir, filename);\n await fs.writeFile(filePath, content, 'utf-8');\n\n const stat = await fs.stat(filePath);\n const manifest = await this.getManifest(jobId);\n\n if (manifest) {\n manifest.artifacts.push({\n milestoneId: milestoneSlug,\n artifactType,\n filePath: path.relative(jobDir, filePath),\n sizeBytes: stat.size,\n createdAt: new Date().toISOString(),\n });\n manifest.updatedAt = new Date().toISOString();\n await this.saveManifest(jobId, manifest);\n }\n\n return filePath;\n }\n\n async getManifest(jobId: string): Promise<JobManifest | null> {\n const manifestPath = path.join(this.getJobDirectory(jobId), 'manifest.json');\n try {\n const data = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(data) as JobManifest;\n } catch {\n return null;\n }\n }\n\n async saveManifest(jobId: string, manifest: JobManifest): Promise<void> {\n const manifestPath = path.join(this.getJobDirectory(jobId), 'manifest.json');\n manifest.updatedAt = new Date().toISOString();\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n }\n\n async markMilestoneCompleted(jobId: string): Promise<void> {\n const manifest = await this.getManifest(jobId);\n if (manifest) {\n manifest.completedMilestones += 1;\n if (manifest.completedMilestones >= manifest.totalMilestones) {\n manifest.status = 'COMPLETED';\n }\n await this.saveManifest(jobId, manifest);\n }\n }\n\n async markJobFailed(jobId: string, errorMsg: string): Promise<void> {\n const manifest = await this.getManifest(jobId);\n if (manifest) {\n manifest.status = 'FAILED';\n manifest.error = errorMsg;\n await this.saveManifest(jobId, manifest);\n }\n }\n}\n","import { Octokit } from '@octokit/rest';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface GitPublishOptions {\n jobId: string;\n localJobDir: string;\n githubToken?: string;\n owner: string;\n repo: string;\n branch?: string;\n commitMessage?: string;\n createPullRequest?: boolean;\n}\n\nexport interface GitPublishResult {\n success: boolean;\n commitSha?: string;\n branch: string;\n pullRequestUrl?: string;\n publishedFilesCount: number;\n error?: string;\n}\n\n/**\n * Publishes generated course artifacts to a designated GitHub Repository (Git-as-CMS)\n */\nexport async function publishToGitHub(options: GitPublishOptions): Promise<GitPublishResult> {\n const token = options.githubToken || process.env.GITHUB_TOKEN;\n if (!token) {\n return {\n success: false,\n branch: options.branch || 'main',\n publishedFilesCount: 0,\n error: 'Missing GITHUB_TOKEN in environment or options',\n };\n }\n\n const octokit = new Octokit({ auth: token });\n const targetBranch = options.branch || `generated/course-${options.jobId}`;\n let publishedFilesCount = 0;\n\n try {\n // 1. Scan all files in local workspace\n const filesToUpload: Array<{ path: string; content: string }> = [];\n\n async function scanDir(currentDir: string) {\n const entries = await fs.readdir(currentDir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(currentDir, entry.name);\n if (entry.isDirectory()) {\n await scanDir(fullPath);\n } else if (entry.isFile() && !entry.name.startsWith('.')) {\n const content = await fs.readFile(fullPath, 'utf-8');\n const relPath = path.relative(options.localJobDir, fullPath);\n filesToUpload.push({ path: relPath, content });\n }\n }\n }\n\n await scanDir(options.localJobDir);\n\n if (filesToUpload.length === 0) {\n return {\n success: false,\n branch: targetBranch,\n publishedFilesCount: 0,\n error: 'No files found in workspace to upload',\n };\n }\n\n // 2. Get reference to base branch (e.g. main)\n const baseBranch = 'main';\n let baseTreeSha: string;\n let baseCommitSha: string;\n\n try {\n const { data: refData } = await octokit.git.getRef({\n owner: options.owner,\n repo: options.repo,\n ref: `heads/${baseBranch}`,\n });\n baseCommitSha = refData.object.sha;\n\n const { data: commitData } = await octokit.git.getCommit({\n owner: options.owner,\n repo: options.repo,\n commit_sha: baseCommitSha,\n });\n baseTreeSha = commitData.tree.sha;\n } catch (e: any) {\n return {\n success: false,\n branch: targetBranch,\n publishedFilesCount: 0,\n error: `Failed to fetch base branch ${baseBranch}: ${e.message}`,\n };\n }\n\n // 3. Create Blobs & Tree Entries\n const treeItems: Array<{ path: string; mode: '100644'; type: 'blob'; sha: string }> = [];\n\n for (const file of filesToUpload) {\n const { data: blobData } = await octokit.git.createBlob({\n owner: options.owner,\n repo: options.repo,\n content: Buffer.from(file.content).toString('base64'),\n encoding: 'base64',\n });\n\n treeItems.push({\n path: file.path,\n mode: '100644',\n type: 'blob',\n sha: blobData.sha,\n });\n publishedFilesCount++;\n }\n\n // 4. Create New Git Tree\n const { data: newTree } = await octokit.git.createTree({\n owner: options.owner,\n repo: options.repo,\n base_tree: baseTreeSha,\n tree: treeItems,\n });\n\n // 5. Create Commit\n const message =\n options.commitMessage ||\n `feat(curriculum): publish generated course artifacts [job:${options.jobId}]`;\n\n const { data: newCommit } = await octokit.git.createCommit({\n owner: options.owner,\n repo: options.repo,\n message,\n tree: newTree.sha,\n parents: [baseCommitSha],\n });\n\n // 6. Update or Create Branch Ref\n try {\n await octokit.git.createRef({\n owner: options.owner,\n repo: options.repo,\n ref: `refs/heads/${targetBranch}`,\n sha: newCommit.sha,\n });\n } catch {\n // If branch already exists, force update ref\n await octokit.git.updateRef({\n owner: options.owner,\n repo: options.repo,\n ref: `heads/${targetBranch}`,\n sha: newCommit.sha,\n force: true,\n });\n }\n\n let prUrl: string | undefined = undefined;\n\n // 7. Optional: Create Pull Request\n if (options.createPullRequest && targetBranch !== baseBranch) {\n try {\n const { data: prData } = await octokit.pulls.create({\n owner: options.owner,\n repo: options.repo,\n title: `[Curriculum AI] Generated Curriculum (${options.jobId})`,\n head: targetBranch,\n base: baseBranch,\n body: `Automated curriculum generation output from job \\`${options.jobId}\\`.\\nContains ${publishedFilesCount} files.`,\n });\n prUrl = prData.html_url;\n } catch {\n // PR might already exist\n }\n }\n\n return {\n success: true,\n commitSha: newCommit.sha,\n branch: targetBranch,\n pullRequestUrl: prUrl,\n publishedFilesCount,\n };\n } catch (error: any) {\n return {\n success: false,\n branch: targetBranch,\n publishedFilesCount,\n error: error.message || String(error),\n };\n }\n}\n","import { createClient, type SupabaseClient } from '@supabase/supabase-js';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface SupabasePublishOptions {\n jobId: string;\n courseTitle: string;\n topic: string;\n language: string;\n milestones: Array<{\n milestoneId: string;\n milestoneName: string;\n lessonSlug: string;\n summary?: string;\n }>;\n supabaseUrl?: string;\n supabaseServiceKey?: string;\n bucketName?: string;\n}\n\nexport interface SupabasePublishResult {\n success: boolean;\n learningPathId?: string;\n syncedMilestonesCount: number;\n uploadedAssetsCount: number;\n error?: string;\n}\n\n/**\n * Publishes metadata and binary assets to Supabase PostgreSQL & Storage Bucket\n */\nexport async function publishToSupabase(\n options: SupabasePublishOptions\n): Promise<SupabasePublishResult> {\n const supabaseUrl = options.supabaseUrl || process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;\n const serviceKey = options.supabaseServiceKey || process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;\n\n if (!supabaseUrl || !serviceKey) {\n return {\n success: false,\n syncedMilestonesCount: 0,\n uploadedAssetsCount: 0,\n error: 'Missing SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY',\n };\n }\n\n const supabase: SupabaseClient = createClient(supabaseUrl, serviceKey);\n const bucketName = options.bucketName || 'learning_resources';\n\n try {\n // 1. Upsert Learning Path / Course record\n const { data: lpData, error: lpError } = await supabase\n .from('learning_paths')\n .upsert(\n {\n code: `LP-${options.jobId}`,\n title: options.courseTitle,\n description: `Auto-generated curriculum on ${options.topic}`,\n language: options.language,\n metadata: {\n jobId: options.jobId,\n topic: options.topic,\n totalMilestones: options.milestones.length,\n generatedAt: new Date().toISOString(),\n },\n },\n { onConflict: 'code' }\n )\n .select('id')\n .single();\n\n const learningPathId = lpData?.id;\n\n // 2. Upsert Lesson / Milestone Records\n let syncedMilestonesCount = 0;\n for (const [index, m] of options.milestones.entries()) {\n const { error: lessonError } = await supabase.from('lessons').upsert(\n {\n code: `L-${options.jobId}-${m.milestoneId}`,\n title: m.milestoneName,\n order_index: index + 1,\n learning_path_id: learningPathId,\n metadata: {\n milestoneId: m.milestoneId,\n lessonSlug: m.lessonSlug,\n summary: m.summary,\n },\n },\n { onConflict: 'code' }\n );\n\n if (!lessonError) {\n syncedMilestonesCount++;\n }\n }\n\n return {\n success: true,\n learningPathId,\n syncedMilestonesCount,\n uploadedAssetsCount: 0,\n };\n } catch (error: any) {\n return {\n success: false,\n syncedMilestonesCount: 0,\n uploadedAssetsCount: 0,\n error: error.message || String(error),\n };\n }\n}\n\n/**\n * Uploads a binary asset (MP3, SCORM zip, PNG) to Supabase Storage Bucket\n */\nexport async function uploadAssetToBucket(\n filePath: string,\n storagePath: string,\n options?: { supabaseUrl?: string; supabaseServiceKey?: string; bucketName?: string }\n): Promise<{ success: boolean; publicUrl?: string; error?: string }> {\n const supabaseUrl = options?.supabaseUrl || process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;\n const serviceKey = options?.supabaseServiceKey || process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;\n\n if (!supabaseUrl || !serviceKey) {\n return { success: false, error: 'Missing Supabase credentials' };\n }\n\n const supabase = createClient(supabaseUrl, serviceKey);\n const bucketName = options?.bucketName || 'course-materials';\n\n try {\n const fileBuffer = await fs.readFile(filePath);\n const { error: uploadError } = await supabase.storage\n .from(bucketName)\n .upload(storagePath, fileBuffer, { upsert: true });\n\n if (uploadError) {\n return { success: false, error: uploadError.message };\n }\n\n const { data } = supabase.storage.from(bucketName).getPublicUrl(storagePath);\n return { success: true, publicUrl: data.publicUrl };\n } catch (error: any) {\n return { success: false, error: error.message || String(error) };\n }\n}\n","import type { ICurriculumStorage } from '../storage/types';\nimport { runCurriculumAIInference } from '../ai/streamRunner';\n\nexport interface ParsedQuizQuestion {\n lessonId: string;\n questionNumber: number;\n questionText: string;\n options: {\n A: string;\n B: string;\n C: string;\n D: string;\n };\n correctAnswer: 'A' | 'B' | 'C' | 'D';\n explanation: string;\n timeLimitSeconds: number;\n}\n\nexport interface DeliveryPackResult {\n projectId: string;\n handoverDoc: string;\n teacherPackFiles: string[];\n studentPackFiles: string[];\n parentPackFiles: string[];\n clientPackFiles: string[];\n quizzesCsv: string;\n quizzesJson: ParsedQuizQuestion[];\n timestamp: string;\n}\n\n/**\n * Extracts and parses all quiz questions from markdown content of QUIZ_*.md files.\n */\nexport function parseQuizMarkdown(content: string, lessonId: string): ParsedQuizQuestion[] {\n const questions: ParsedQuizQuestion[] = [];\n const lines = content.split('\\n');\n\n let currentQuestion: Partial<ParsedQuizQuestion> | null = null;\n let qCounter = 1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Match question start e.g. \"### Câu 1:\", \"**Câu 1:**\", \"1. Question...\", \"### Question 1:\"\n const qMatch = line.match(/^(?:###\\s*)?(?:Câu|\\*\\*Câu|Question|\\*\\*Question|\\d+\\.)\\s*(\\d+)?[:\\.]?\\s*(.*)/i);\n if (qMatch && (line.includes('?') || line.includes(':') || line.startsWith('###') || line.startsWith('**Câu'))) {\n if (currentQuestion && currentQuestion.questionText && currentQuestion.options) {\n questions.push({\n lessonId,\n questionNumber: currentQuestion.questionNumber || qCounter++,\n questionText: currentQuestion.questionText,\n options: currentQuestion.options as any,\n correctAnswer: currentQuestion.correctAnswer || 'A',\n explanation: currentQuestion.explanation || '',\n timeLimitSeconds: 60,\n });\n }\n\n currentQuestion = {\n lessonId,\n questionNumber: qMatch[1] ? parseInt(qMatch[1]) : qCounter,\n questionText: qMatch[2] ? qMatch[2].replace(/\\*\\*/g, '').trim() : line.replace(/^###|\\*\\*/g, '').trim(),\n options: { A: '', B: '', C: '', D: '' },\n correctAnswer: 'A',\n explanation: '',\n timeLimitSeconds: 60,\n };\n continue;\n }\n\n if (!currentQuestion) continue;\n\n // Match options: A. ..., B. ..., C. ..., D. ... or - A. ...\n const optMatch = line.match(/^[-*]?\\s*([A-D])[\\.\\)]\\s*(.*)/i);\n if (optMatch) {\n const optKey = optMatch[1].toUpperCase() as 'A' | 'B' | 'C' | 'D';\n let optText = optMatch[2].trim();\n\n // Check if correct answer is marked on the same line e.g. \"A. Swift (Đáp án đúng)\" or \"✅\"\n if (optText.includes('(Đáp án đúng)') || optText.includes('✅') || optText.includes('(Correct)')) {\n currentQuestion.correctAnswer = optKey;\n optText = optText.replace(/\\(Đáp án đúng\\)|\\(Correct\\)|✅/g, '').trim();\n }\n\n if (currentQuestion.options) {\n currentQuestion.options[optKey] = optText;\n }\n continue;\n }\n\n // Match correct answer tag e.g. \"**Đáp án đúng:** B\" or \"- **Đáp án:** A\"\n const ansMatch = line.match(/(?:Đáp án đúng|Đáp án|Correct Answer|Answer)[:\\s\\*]+([A-D])/i);\n if (ansMatch) {\n currentQuestion.correctAnswer = ansMatch[1].toUpperCase() as 'A' | 'B' | 'C' | 'D';\n continue;\n }\n\n // Match explanation e.g. \"**Giải thích:** ...\" or \"- **Giải thích:** ...\"\n const expMatch = line.match(/(?:Giải thích|Explanation)[:\\s\\*]+(.*)/i);\n if (expMatch) {\n currentQuestion.explanation = expMatch[1].replace(/\\*\\*/g, '').trim();\n continue;\n }\n }\n\n // Push the last question\n if (currentQuestion && currentQuestion.questionText && currentQuestion.options) {\n questions.push({\n lessonId,\n questionNumber: currentQuestion.questionNumber || qCounter,\n questionText: currentQuestion.questionText,\n options: currentQuestion.options as any,\n correctAnswer: currentQuestion.correctAnswer || 'A',\n explanation: currentQuestion.explanation || '',\n timeLimitSeconds: 60,\n });\n }\n\n return questions;\n}\n\n/**\n * Converts parsed questions to standard CSV formats (Kahoot, Canvas, Quizizz).\n */\nexport function formatQuizzesToCsv(\n questions: ParsedQuizQuestion[],\n format: 'kahoot' | 'canvas' | 'quizizz' = 'kahoot'\n): string {\n if (format === 'kahoot') {\n // Kahoot format: Question - max 120 chars | Answer 1 | Answer 2 | Answer 3 | Answer 4 | Time limit (sec) | Correct answer(s)\n const header = 'Question,Answer 1,Answer 2,Answer 3,Answer 4,Time limit (sec),Correct answer(s)\\n';\n const rows = questions.map(q => {\n const cleanQ = `\"${q.questionText.replace(/\"/g, '\"\"')}\"`;\n const a1 = `\"${(q.options.A || '').replace(/\"/g, '\"\"')}\"`;\n const a2 = `\"${(q.options.B || '').replace(/\"/g, '\"\"')}\"`;\n const a3 = `\"${(q.options.C || '').replace(/\"/g, '\"\"')}\"`;\n const a4 = `\"${(q.options.D || '').replace(/\"/g, '\"\"')}\"`;\n const correctIndex = q.correctAnswer === 'A' ? 1 : q.correctAnswer === 'B' ? 2 : q.correctAnswer === 'C' ? 3 : 4;\n return `${cleanQ},${a1},${a2},${a3},${a4},${q.timeLimitSeconds || 60},${correctIndex}`;\n }).join('\\n');\n return header + rows;\n }\n\n if (format === 'quizizz') {\n // Quizizz format: Question Text, Question Type, Option 1, Option 2, Option 3, Option 4, Option 5, Correct Answer, Time in seconds\n const header = 'Question Text,Question Type,Option 1,Option 2,Option 3,Option 4,Option 5,Correct Answer,Time in seconds\\n';\n const rows = questions.map(q => {\n const cleanQ = `\"${q.questionText.replace(/\"/g, '\"\"')}\"`;\n const a1 = `\"${(q.options.A || '').replace(/\"/g, '\"\"')}\"`;\n const a2 = `\"${(q.options.B || '').replace(/\"/g, '\"\"')}\"`;\n const a3 = `\"${(q.options.C || '').replace(/\"/g, '\"\"')}\"`;\n const a4 = `\"${(q.options.D || '').replace(/\"/g, '\"\"')}\"`;\n const correctIndex = q.correctAnswer === 'A' ? 1 : q.correctAnswer === 'B' ? 2 : q.correctAnswer === 'C' ? 3 : 4;\n return `${cleanQ},Multiple Choice,${a1},${a2},${a3},${a4},,${correctIndex},${q.timeLimitSeconds || 60}`;\n }).join('\\n');\n return header + rows;\n }\n\n // Canvas LMS / Standard format\n const header = 'Lesson ID,Question Number,Question Text,Option A,Option B,Option C,Option D,Correct Answer,Explanation\\n';\n const rows = questions.map(q => {\n return `\"${q.lessonId}\",${q.questionNumber},\"${q.questionText.replace(/\"/g, '\"\"')}\",\"${(q.options.A || '').replace(/\"/g, '\"\"')}\",\"${(q.options.B || '').replace(/\"/g, '\"\"')}\",\"${(q.options.C || '').replace(/\"/g, '\"\"')}\",\"${(q.options.D || '').replace(/\"/g, '\"\"')}\",\"${q.correctAnswer}\",\"${(q.explanation || '').replace(/\"/g, '\"\"')}\"`;\n }).join('\\n');\n return header + rows;\n}\n\n/**\n * Extracts and exports all quiz files in the project to CSV & JSON.\n */\nexport async function exportAllProjectQuizzes(\n storage: ICurriculumStorage,\n projectId: string,\n format: 'kahoot' | 'canvas' | 'quizizz' = 'kahoot'\n): Promise<{ csv: string; questions: ParsedQuizQuestion[] }> {\n const lessons = await storage.listLessons(projectId);\n const allQuestions: ParsedQuizQuestion[] = [];\n\n for (const l of lessons) {\n const unitCode = l.lessonId.split('_')[0] || 'U01';\n const possiblePaths = [\n `_content/${unitCode}/QUIZ_${l.lessonId}.md`,\n `lessons/${l.lessonId}/QUIZ_${l.lessonId}.md`,\n `QUIZ_${l.lessonId}.md`,\n ];\n\n for (const p of possiblePaths) {\n const content = await storage.readArtifact(projectId, p);\n if (content) {\n const parsed = parseQuizMarkdown(content, l.lessonId);\n allQuestions.push(...parsed);\n break;\n }\n }\n }\n\n const csv = formatQuizzesToCsv(allQuestions, format);\n await storage.saveArtifact(projectId, `_released/quizzes_${format}.csv`, csv);\n await storage.saveArtifact(projectId, `_released/QUIZ_BANK.json`, JSON.stringify(allQuestions, null, 2));\n\n return { csv, questions: allQuestions };\n}\n\n/**\n * Builds the 4 standard Delivery Packages and generates HANDOVER_DOCUMENT.md.\n */\nexport async function buildDeliveryPackages(\n storage: ICurriculumStorage,\n projectId: string,\n onProgress?: (agent: string, message: string) => void\n): Promise<DeliveryPackResult> {\n onProgress?.('@packager', '📦 Bắt đầu quy trình kiểm tra chất lượng và phân phối 4 Gói Bàn Giao...');\n\n const statusReport = await storage.getProjectStatus(projectId);\n const framework = (await storage.readSotDocument(projectId, 'CURRICULUM_FRAMEWORK.md')) || '';\n const brief = (await storage.readSotDocument(projectId, 'PROJECT_BRIEF.md')) || '';\n const dateStr = new Date().toISOString().split('T')[0];\n\n // 1. Export Quizzes to CSV & JSON\n onProgress?.('@assessor', '📊 Đang trích xuất toàn bộ ngân hàng câu hỏi trắc nghiệm sang chuẩn Kahoot & Canvas CSV...');\n const { csv: quizzesCsv, questions: quizzesJson } = await exportAllProjectQuizzes(storage, projectId, 'kahoot');\n\n // 2. Package Teacher Pack\n onProgress?.('@packager', '👨‍🏫 Đang lắp ráp Teacher Pack (Giáo án, Kế hoạch bài dạy, Lời thoại)...');\n const teacherHandbook = `---\nid: \"${projectId.toUpperCase()}-TEACHER-HANDBOOK\"\ntitle: \"Teacher Handbook: ${projectId.toUpperCase()}\"\ntype: \"HANDBOOK\"\nphase: \"P4\"\ndate: \"${dateStr}\"\n---\n\n# 👨‍🏫 TEACHER HANDBOOK & SCRIPT GUIDE\n\n## 1. Tổng Quan Khóa Học\n${brief.slice(0, 1000)}\n\n## 2. Khung Phân Bổ Sư Phạm 5E & Thời Gian Giảng Dạy\n- Mỗi buổi học chuẩn hóa 90 phút.\n- Tuân thủ nghiêm ngặt tiến trình: Engage (10m) $\\\\rightarrow$ Explore (20m) $\\\\rightarrow$ Explain (25m) $\\\\rightarrow$ Elaborate (25m) $\\\\rightarrow$ Evaluate (10m).\n\n## 3. Danh Mục Bài Giảng (Lesson Plans)\n${statusReport.lessons.map(l => `- \\`LESSON_${l.lessonId}.md\\``).join('\\n') || '- Đang cập nhật'}\n`;\n await storage.saveArtifact(projectId, `_released/teacher_pack/TEACHER_HANDBOOK.md`, teacherHandbook);\n\n // 3. Package Student Pack\n onProgress?.('@packager', '🧑‍🎓 Đang đóng gói Student Pack (Slide bài giảng, Lab thực hành, Phiếu học tập)...');\n const studentSyllabus = `---\nid: \"${projectId.toUpperCase()}-STUDENT-SYLLABUS\"\ntitle: \"Student Syllabus: ${projectId.toUpperCase()}\"\ntype: \"SYLLABUS\"\nphase: \"P4\"\ndate: \"${dateStr}\"\n---\n\n# 🧑‍🎓 HỒ SƠ HỌC TẬP & LỘ TRÌNH THỰC HÀNH\n\n## 1. Mục Tiêu Năng Lực Đầu Ra\nHọc viên sau khi hoàn thành khóa học sẽ làm chủ toàn diện các kỹ năng và kiến thức đã định nghĩa trong đồ thị tri thức.\n\n## 2. Danh Mục Slide & Lab Thực Hành\n${statusReport.lessons.map(l => `- **${l.lessonId}:** Slide \\`SLIDE_${l.lessonId}.md\\` + Lab \\`ACT_${l.lessonId}.md\\``).join('\\n') || '- Đang cập nhật'}\n`;\n await storage.saveArtifact(projectId, `_released/student_pack/STUDENT_SYLLABUS.md`, studentSyllabus);\n\n // 4. Package Parent Pack\n onProgress?.('@packager', '👨‍👩‍👧 Đang lập Báo cáo Bàn giao Phụ huynh (Parent Pack)...');\n const parentOverview = `---\nid: \"${projectId.toUpperCase()}-PARENT-OVERVIEW\"\ntitle: \"Parent Overview: ${projectId.toUpperCase()}\"\ntype: \"REPORT\"\nphase: \"P4\"\ndate: \"${dateStr}\"\n---\n\n# 👨‍👩‍👧 BÁO CÁO TIẾN ĐỘ & KẾ HOẠCH HỌC TẬP DÀNH CHO PHỤ HUYNH\n\n- **Tên chương trình:** ${projectId.toUpperCase()}\n- **Thời lượng:** ${statusReport.totalLessons} bài học (Chuẩn 90 phút/buổi).\n- **Mục tiêu phát triển:** Giúp học sinh làm chủ tư duy giải quyết vấn đề, tự tay phát triển các đồ án công nghệ thực tế và tự tin trước các kỳ thi đánh giá năng lực.\n`;\n await storage.saveArtifact(projectId, `_released/parent_pack/COURSE_OVERVIEW.md`, parentOverview);\n\n // 5. Package Client Pack & Handover Document\n onProgress?.('@packager', '🏢 Đang hoàn tất Client Pack & Biên bản Nghiệm thu Bàn giao (HANDOVER_DOCUMENT.md)...');\n const handoverDoc = `---\nid: \"${projectId.toUpperCase()}-HANDOVER\"\ntitle: \"Handover Document: ${projectId.toUpperCase()}\"\ntype: \"HANDOVER_DOCUMENT\"\ncreated_by: \"Curriculum OS Packager\"\nphase: \"P4\"\ndeliverable: \"P4-T1\"\nversion: \"v1.0\"\ndate: \"${dateStr}\"\ntemplate_contract: \"artifact-template-v1\"\n---\n\n# 🏢 BIÊN BẢN NGHIỆM THU & BÀN GIAO HỌC LIỆU (HANDOVER DOCUMENT)\n\n## 1. Thông Tin Nghiệm Thu Dự Án\n- **Mã dự án:** \\`${projectId}\\`\n- **Ngày nghiệm thu bàn giao:** ${dateStr}\n- **Đơn vị phát triển:** Curriculum OS Automation Team\n- **Tiêu chuẩn chất lượng:** 100% Khớp mục tiêu Bloom, Thang đo 5E/EDP, Code sạch không lỗi cú pháp.\n\n## 2. Thống Kê Học Liệu Bàn Giao\n- **Tài liệu Nền tảng (SOT):** ${statusReport.sotReadiness.filter(s => s.exists).length}/7 Files Sẵn sàng (100%).\n- **Tổng số bài học hoàn tất:** ${statusReport.completedCount}/${statusReport.totalLessons} bài học.\n- **Tổng số câu hỏi trắc nghiệm trích xuất:** ${quizzesJson.length} câu hỏi.\n- **Định dạng xuất khẩu:** Markdown chuẩn GitHub, Kahoot CSV, Canvas CSV, QUIZ_BANK JSON.\n\n## 3. Cấu Trúc 4 Gói Bàn Giao Đã Đóng Gói (\\`_released/\\`)\n- 📁 **\\`_released/teacher_pack/\\`**: \\`TEACHER_HANDBOOK.md\\` + Toàn bộ Giáo án \\`LESSON_*.md\\`\n- 📁 **\\`_released/student_pack/\\`**: \\`STUDENT_SYLLABUS.md\\` + Slide \\`SLIDE_*.md\\` + Lab \\`ACT_*.md\\`\n- 📁 **\\`_released/parent_pack/\\`**: \\`COURSE_OVERVIEW.md\\`\n- 📁 **\\`_released/client_pack/\\`**: 7 Files SOT + \\`ALIGNMENT_MATRIX.md\\` + \\`HANDOVER_DOCUMENT.md\\`\n- 📁 **\\`_released/quizzes_kahoot.csv\\`**: Ngân hàng trắc nghiệm chuẩn Kahoot.\n- 📁 **\\`_released/QUIZ_BANK.json\\`**: Ngân hàng JSON tương thích Interactive Quiz Kit.\n\n---\n- **Đại diện Đơn vị Phát triển:** @packager (Curriculum OS)\n- **Trạng thái:** ✅ **SẴN SÀNG TRIỂN KHAI THƯƠNG MẠI (COMMERCIAL READY)**\n`;\n await storage.saveArtifact(projectId, `_released/client_pack/HANDOVER_DOCUMENT.md`, handoverDoc);\n await storage.saveArtifact(projectId, `HANDOVER_DOCUMENT.md`, handoverDoc);\n\n onProgress?.('@packager', `🎉 Bàn giao thành công toàn bộ 4 gói học liệu vào thư mục \\`_released/\\`!`);\n\n return {\n projectId,\n handoverDoc,\n teacherPackFiles: [`_released/teacher_pack/TEACHER_HANDBOOK.md`],\n studentPackFiles: [`_released/student_pack/STUDENT_SYLLABUS.md`],\n parentPackFiles: [`_released/parent_pack/COURSE_OVERVIEW.md`],\n clientPackFiles: [`_released/client_pack/HANDOVER_DOCUMENT.md`, `HANDOVER_DOCUMENT.md`],\n quizzesCsv,\n quizzesJson,\n timestamp: dateStr,\n };\n}\n"]}