@thanh01.pmt/curriculum-kit 1.4.23 → 1.4.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +45 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +45 -19
- package/dist/index.mjs.map +1 -1
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -26203,7 +26203,22 @@ async function produceSingleLesson(storage, projectId, lessonId, options = {}) {
|
|
|
26203
26203
|
const framework = await storage.readSotDocument(projectId, "CURRICULUM_FRAMEWORK.md") || "";
|
|
26204
26204
|
const styleGuide = await storage.readSotDocument(projectId, "CONTENT_STYLE_GUIDE.md") || "";
|
|
26205
26205
|
const refPack = await storage.readSotDocument(projectId, "REFERENCE_PACK.md") || "";
|
|
26206
|
+
let currentPlanHash;
|
|
26207
|
+
try {
|
|
26208
|
+
const planRaw0 = await storage.readArtifact(projectId, "_sot/CURRICULUM_PLAN.json");
|
|
26209
|
+
if (planRaw0) currentPlanHash = JSON.parse(planRaw0).plan_hash;
|
|
26210
|
+
} catch {
|
|
26211
|
+
}
|
|
26206
26212
|
await storage.readSotDocument(projectId, "LEARNER_PROFILE.md") || "";
|
|
26213
|
+
const isStaleVsPlan = (content) => {
|
|
26214
|
+
if (!content || !currentPlanHash) return false;
|
|
26215
|
+
const m = content.match(/plan_hash:\s*"([0-9a-f]+)"/);
|
|
26216
|
+
return !!m && m[1] !== currentPlanHash;
|
|
26217
|
+
};
|
|
26218
|
+
const stampPlanHash = (content) => {
|
|
26219
|
+
if (!currentPlanHash || content.includes('plan_hash: "' + currentPlanHash + '"')) return content;
|
|
26220
|
+
return content + '\n---\nplan_hash: "' + currentPlanHash + '"\n- **Plan reference:** ' + currentPlanHash + "\n";
|
|
26221
|
+
};
|
|
26207
26222
|
const slcMarkdown = options.sectionLanguageContract || await storage.readSotDocument(projectId, "SECTION_LANGUAGE_CONTRACT.md") || "";
|
|
26208
26223
|
let targetLang = options.targetLanguage;
|
|
26209
26224
|
if (!targetLang) {
|
|
@@ -26414,7 +26429,10 @@ ${sg}${standardsBlock}${glossaryBlock}${buildGroundTruthBlock()}${sessionSliceBl
|
|
|
26414
26429
|
const lessonRelPath = `_content/${unitCode}/LESSON_${lessonCode}.md`;
|
|
26415
26430
|
const existingLessonContent = await storage.readArtifact(projectId, lessonRelPath);
|
|
26416
26431
|
let lessonContent = existingLessonContent || "";
|
|
26417
|
-
if (artifactScope.includes("LESSON") && (!existingLessonContent || force)) {
|
|
26432
|
+
if (artifactScope.includes("LESSON") && (!existingLessonContent || force || isStaleVsPlan(existingLessonContent))) {
|
|
26433
|
+
if (existingLessonContent && !force && isStaleVsPlan(existingLessonContent)) {
|
|
26434
|
+
onProgress?.("@content", `[STALENESS] LESSON_${lessonCode} was generated under a different plan_hash \u2014 regenerating against the current plan.`);
|
|
26435
|
+
}
|
|
26418
26436
|
onProgress?.("@content", `[1/4] Authoring Master Lesson Plan (${pedagogyLabel}): \`LESSON_${lessonCode}.md\` (${lessonTitle})...`);
|
|
26419
26437
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
26420
26438
|
const mediaDirective = options.mediaPolicy && options.mediaPolicy.maxGenImagesPerArtifact > 0 ? `
|
|
@@ -26485,7 +26503,7 @@ Fix ALL issues above and output the complete corrected document.` }],
|
|
|
26485
26503
|
} else {
|
|
26486
26504
|
lessonContent = lintReport.autoFixedContent || rawLesson;
|
|
26487
26505
|
}
|
|
26488
|
-
await storage.saveArtifact(projectId, lessonRelPath, lessonContent);
|
|
26506
|
+
await storage.saveArtifact(projectId, lessonRelPath, stampPlanHash(lessonContent));
|
|
26489
26507
|
producedArtifacts.push(`LESSON_${lessonCode}.md`);
|
|
26490
26508
|
}
|
|
26491
26509
|
const contentHash = lessonContent ? computeContentHash(lessonContent) : void 0;
|
|
@@ -26830,7 +26848,8 @@ ${lessonExcerpt}${symbolLedgerBlock}`;
|
|
|
26830
26848
|
});
|
|
26831
26849
|
};
|
|
26832
26850
|
const actRelPath = `_content/${unitCode}/ACT_${lessonCode}.md`;
|
|
26833
|
-
|
|
26851
|
+
const existingAct = await storage.readArtifact(projectId, actRelPath);
|
|
26852
|
+
if (artifactScope.includes("ACT") && (!existingAct || force || isStaleVsPlan(existingAct))) {
|
|
26834
26853
|
onProgress?.("@activity", `[2/4] Authoring Hands-on Lab: \`ACT_${lessonCode}.md\`...`);
|
|
26835
26854
|
const actDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
26836
26855
|
const actPrompt = `You are @activity (Lead Hands-on STEM & Laboratory Exercise Designer).
|
|
@@ -26890,7 +26909,7 @@ ${buildHeadingDirective("ACT", slcMarkdown, targetLang)}`;
|
|
|
26890
26909
|
rawError: rawAct || "Empty AI response"
|
|
26891
26910
|
});
|
|
26892
26911
|
}
|
|
26893
|
-
await storage.saveArtifact(projectId, actRelPath, rawAct);
|
|
26912
|
+
await storage.saveArtifact(projectId, actRelPath, stampPlanHash(rawAct));
|
|
26894
26913
|
await storage.updateArtifactState(projectId, lessonCode, "ACT", {
|
|
26895
26914
|
state: "completed",
|
|
26896
26915
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -26900,7 +26919,8 @@ ${buildHeadingDirective("ACT", slcMarkdown, targetLang)}`;
|
|
|
26900
26919
|
await judgeSat("ACT", rawAct);
|
|
26901
26920
|
}
|
|
26902
26921
|
const quizRelPath = `_content/${unitCode}/QUIZ_${lessonCode}.md`;
|
|
26903
|
-
|
|
26922
|
+
const existingQuiz = await storage.readArtifact(projectId, quizRelPath);
|
|
26923
|
+
if (artifactScope.includes("QUIZ") && (!existingQuiz || force || isStaleVsPlan(existingQuiz))) {
|
|
26904
26924
|
onProgress?.("@assessor", `[3/4] Authoring Assessment Bank: \`QUIZ_${lessonCode}.md\`...`);
|
|
26905
26925
|
const quizDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
26906
26926
|
const quizPrompt = `You are @assessor (Lead Psychometrician & Competency Assessment Specialist).
|
|
@@ -26954,7 +26974,7 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
26954
26974
|
rawError: rawQuiz || "Empty AI response"
|
|
26955
26975
|
});
|
|
26956
26976
|
}
|
|
26957
|
-
await storage.saveArtifact(projectId, quizRelPath, rawQuiz);
|
|
26977
|
+
await storage.saveArtifact(projectId, quizRelPath, stampPlanHash(rawQuiz));
|
|
26958
26978
|
await storage.updateArtifactState(projectId, lessonCode, "QUIZ", {
|
|
26959
26979
|
state: "completed",
|
|
26960
26980
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -26964,7 +26984,8 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
26964
26984
|
await judgeSat("QUIZ", rawQuiz);
|
|
26965
26985
|
}
|
|
26966
26986
|
const slideRelPath = `_content/${unitCode}/SLIDE_${lessonCode}.md`;
|
|
26967
|
-
|
|
26987
|
+
const existingSlide = await storage.readArtifact(projectId, slideRelPath);
|
|
26988
|
+
if (artifactScope.includes("SLIDE") && (!existingSlide || force || isStaleVsPlan(existingSlide))) {
|
|
26968
26989
|
onProgress?.("@illustrator", `[4/4] Authoring Presentation Slide Deck: \`SLIDE_${lessonCode}.md\`...`);
|
|
26969
26990
|
const isHtmlEngine = options.slidesEngine !== "marp";
|
|
26970
26991
|
if (isHtmlEngine) {
|
|
@@ -26998,7 +27019,7 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
26998
27019
|
let deckJson = workflowResult.deckJson;
|
|
26999
27020
|
const markdownWrapper = workflowResult.markdownWrapper;
|
|
27000
27021
|
let validation = presentationKitAi?.validateHtmlSlideDeck ? presentationKitAi.validateHtmlSlideDeck(deckJson, true) : deckJson && Array.isArray(deckJson.slides) ? { valid: true, score: 95, issues: [], slideCount: deckJson.slides.length} : { valid: false, score: 0, issues: [{ message: "Malformed JSON slide deck" }]};
|
|
27001
|
-
await storage.saveArtifact(projectId, slideRelPath, markdownWrapper);
|
|
27022
|
+
await storage.saveArtifact(projectId, slideRelPath, stampPlanHash(markdownWrapper));
|
|
27002
27023
|
producedArtifacts.push(`SLIDE_${lessonCode}.md`);
|
|
27003
27024
|
if (deckJson) {
|
|
27004
27025
|
const deckJsonStr = JSON.stringify(deckJson, null, 2);
|
|
@@ -27089,7 +27110,7 @@ footer: "Curriculum OS \u2022 ${lessonCode} (${pedagogyLabel})"
|
|
|
27089
27110
|
rawError: rawSlide || "Empty AI response"
|
|
27090
27111
|
});
|
|
27091
27112
|
}
|
|
27092
|
-
await storage.saveArtifact(projectId, slideRelPath, rawSlide);
|
|
27113
|
+
await storage.saveArtifact(projectId, slideRelPath, stampPlanHash(rawSlide));
|
|
27093
27114
|
await storage.updateArtifactState(projectId, lessonCode, "SLIDE", {
|
|
27094
27115
|
state: "completed",
|
|
27095
27116
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27100,7 +27121,8 @@ footer: "Curriculum OS \u2022 ${lessonCode} (${pedagogyLabel})"
|
|
|
27100
27121
|
}
|
|
27101
27122
|
}
|
|
27102
27123
|
const guideRelPath = `_content/${unitCode}/GUIDE_${lessonCode}.md`;
|
|
27103
|
-
|
|
27124
|
+
const existingGuide = await storage.readArtifact(projectId, guideRelPath);
|
|
27125
|
+
if (artifactScope.includes("GUIDE") && (!existingGuide || force || isStaleVsPlan(existingGuide))) {
|
|
27104
27126
|
onProgress?.("@content", `Authoring Teacher Guide: \`GUIDE_${lessonCode}.md\`...`, { artifactType: "GUIDE" });
|
|
27105
27127
|
const guideDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27106
27128
|
const guidePrompt = `You are @content (Senior Curriculum Developer & Teacher Facilitation Specialist).
|
|
@@ -27140,7 +27162,7 @@ ${buildHeadingDirective("GUIDE", slcMarkdown, targetLang)}`;
|
|
|
27140
27162
|
}
|
|
27141
27163
|
);
|
|
27142
27164
|
if (rawGuide && !rawGuide.startsWith("\u26A0\uFE0F") && rawGuide.length >= 200) {
|
|
27143
|
-
await storage.saveArtifact(projectId, guideRelPath, rawGuide);
|
|
27165
|
+
await storage.saveArtifact(projectId, guideRelPath, stampPlanHash(rawGuide));
|
|
27144
27166
|
await storage.updateArtifactState(projectId, lessonCode, "GUIDE", {
|
|
27145
27167
|
state: "completed",
|
|
27146
27168
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27151,7 +27173,8 @@ ${buildHeadingDirective("GUIDE", slcMarkdown, targetLang)}`;
|
|
|
27151
27173
|
}
|
|
27152
27174
|
}
|
|
27153
27175
|
const handoutRelPath = `_content/${unitCode}/HANDOUT_${lessonCode}.md`;
|
|
27154
|
-
|
|
27176
|
+
const existingHandout = await storage.readArtifact(projectId, handoutRelPath);
|
|
27177
|
+
if (artifactScope.includes("HANDOUT") && (!existingHandout || force || isStaleVsPlan(existingHandout))) {
|
|
27155
27178
|
onProgress?.("@content", `Authoring Student Handout: \`HANDOUT_${lessonCode}.md\`...`, { artifactType: "HANDOUT" });
|
|
27156
27179
|
const handoutDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27157
27180
|
const handoutPrompt = `You are @content (Educational Content Specialist).
|
|
@@ -27191,7 +27214,7 @@ ${buildHeadingDirective("HANDOUT", slcMarkdown, targetLang)}`;
|
|
|
27191
27214
|
}
|
|
27192
27215
|
);
|
|
27193
27216
|
if (rawHandout && !rawHandout.startsWith("\u26A0\uFE0F") && rawHandout.length >= 200) {
|
|
27194
|
-
await storage.saveArtifact(projectId, handoutRelPath, rawHandout);
|
|
27217
|
+
await storage.saveArtifact(projectId, handoutRelPath, stampPlanHash(rawHandout));
|
|
27195
27218
|
await storage.updateArtifactState(projectId, lessonCode, "HANDOUT", {
|
|
27196
27219
|
state: "completed",
|
|
27197
27220
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27202,7 +27225,8 @@ ${buildHeadingDirective("HANDOUT", slcMarkdown, targetLang)}`;
|
|
|
27202
27225
|
}
|
|
27203
27226
|
}
|
|
27204
27227
|
const wksRelPath = `_content/${unitCode}/WKS_${lessonCode}.md`;
|
|
27205
|
-
|
|
27228
|
+
const existingWks = await storage.readArtifact(projectId, wksRelPath);
|
|
27229
|
+
if (artifactScope.includes("WKS") && (!existingWks || force || isStaleVsPlan(existingWks))) {
|
|
27206
27230
|
onProgress?.("@content", `Authoring Student Worksheet: \`WKS_${lessonCode}.md\`...`, { artifactType: "WKS" });
|
|
27207
27231
|
const wksDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27208
27232
|
const wksPrompt = `You are @content (Instructional Activity & Worksheet Designer).
|
|
@@ -27246,7 +27270,7 @@ ${buildHeadingDirective("WKS", slcMarkdown, targetLang)}`;
|
|
|
27246
27270
|
}
|
|
27247
27271
|
);
|
|
27248
27272
|
if (rawWks && !rawWks.startsWith("\u26A0\uFE0F") && rawWks.length >= 200) {
|
|
27249
|
-
await storage.saveArtifact(projectId, wksRelPath, rawWks);
|
|
27273
|
+
await storage.saveArtifact(projectId, wksRelPath, stampPlanHash(rawWks));
|
|
27250
27274
|
await storage.updateArtifactState(projectId, lessonCode, "WKS", {
|
|
27251
27275
|
state: "completed",
|
|
27252
27276
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27257,7 +27281,8 @@ ${buildHeadingDirective("WKS", slcMarkdown, targetLang)}`;
|
|
|
27257
27281
|
}
|
|
27258
27282
|
}
|
|
27259
27283
|
const codeRelPath = `_content/${unitCode}/CODE_${lessonCode}.md`;
|
|
27260
|
-
|
|
27284
|
+
const existingCode = await storage.readArtifact(projectId, codeRelPath);
|
|
27285
|
+
if ((artifactScope.includes("CODE") || artifactScope.includes("CODE_LAB")) && (!existingCode || force || isStaleVsPlan(existingCode))) {
|
|
27261
27286
|
onProgress?.("@activity", `Authoring Executable Code Lab: \`CODE_${lessonCode}.md\`...`, { artifactType: "CODE" });
|
|
27262
27287
|
const codeDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27263
27288
|
const codePrompt = `You are @activity & @tech_sme (Lead Software Engineer & Technical SME).
|
|
@@ -27305,7 +27330,7 @@ ${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
|
|
|
27305
27330
|
}
|
|
27306
27331
|
);
|
|
27307
27332
|
if (rawCode && !rawCode.startsWith("\u26A0\uFE0F") && rawCode.length >= 200) {
|
|
27308
|
-
await storage.saveArtifact(projectId, codeRelPath, rawCode);
|
|
27333
|
+
await storage.saveArtifact(projectId, codeRelPath, stampPlanHash(rawCode));
|
|
27309
27334
|
await storage.updateArtifactState(projectId, lessonCode, "CODE", {
|
|
27310
27335
|
state: "completed",
|
|
27311
27336
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27321,7 +27346,8 @@ ${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
|
|
|
27321
27346
|
}
|
|
27322
27347
|
}
|
|
27323
27348
|
const extRelPath = `_content/${unitCode}/EXT_${lessonCode}.md`;
|
|
27324
|
-
|
|
27349
|
+
const existingExt = await storage.readArtifact(projectId, extRelPath);
|
|
27350
|
+
if (artifactScope.includes("EXT") && (!existingExt || force || isStaleVsPlan(existingExt))) {
|
|
27325
27351
|
onProgress?.("@activity", `Authoring Advanced Extension Challenge: \`EXT_${lessonCode}.md\`...`, { artifactType: "EXT" });
|
|
27326
27352
|
const extDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27327
27353
|
const isVi = targetLang === "vi";
|
|
@@ -27391,7 +27417,7 @@ ${buildHeadingDirective("EXT", slcMarkdown, targetLang)}`;
|
|
|
27391
27417
|
}
|
|
27392
27418
|
);
|
|
27393
27419
|
if (rawExt && !rawExt.startsWith("\u26A0\uFE0F") && rawExt.length >= 200) {
|
|
27394
|
-
await storage.saveArtifact(projectId, extRelPath, rawExt);
|
|
27420
|
+
await storage.saveArtifact(projectId, extRelPath, stampPlanHash(rawExt));
|
|
27395
27421
|
await storage.updateArtifactState(projectId, lessonCode, "EXT", {
|
|
27396
27422
|
state: "completed",
|
|
27397
27423
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|