@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.mjs
CHANGED
|
@@ -26191,7 +26191,22 @@ async function produceSingleLesson(storage, projectId, lessonId, options = {}) {
|
|
|
26191
26191
|
const framework = await storage.readSotDocument(projectId, "CURRICULUM_FRAMEWORK.md") || "";
|
|
26192
26192
|
const styleGuide = await storage.readSotDocument(projectId, "CONTENT_STYLE_GUIDE.md") || "";
|
|
26193
26193
|
const refPack = await storage.readSotDocument(projectId, "REFERENCE_PACK.md") || "";
|
|
26194
|
+
let currentPlanHash;
|
|
26195
|
+
try {
|
|
26196
|
+
const planRaw0 = await storage.readArtifact(projectId, "_sot/CURRICULUM_PLAN.json");
|
|
26197
|
+
if (planRaw0) currentPlanHash = JSON.parse(planRaw0).plan_hash;
|
|
26198
|
+
} catch {
|
|
26199
|
+
}
|
|
26194
26200
|
await storage.readSotDocument(projectId, "LEARNER_PROFILE.md") || "";
|
|
26201
|
+
const isStaleVsPlan = (content) => {
|
|
26202
|
+
if (!content || !currentPlanHash) return false;
|
|
26203
|
+
const m = content.match(/plan_hash:\s*"([0-9a-f]+)"/);
|
|
26204
|
+
return !!m && m[1] !== currentPlanHash;
|
|
26205
|
+
};
|
|
26206
|
+
const stampPlanHash = (content) => {
|
|
26207
|
+
if (!currentPlanHash || content.includes('plan_hash: "' + currentPlanHash + '"')) return content;
|
|
26208
|
+
return content + '\n---\nplan_hash: "' + currentPlanHash + '"\n- **Plan reference:** ' + currentPlanHash + "\n";
|
|
26209
|
+
};
|
|
26195
26210
|
const slcMarkdown = options.sectionLanguageContract || await storage.readSotDocument(projectId, "SECTION_LANGUAGE_CONTRACT.md") || "";
|
|
26196
26211
|
let targetLang = options.targetLanguage;
|
|
26197
26212
|
if (!targetLang) {
|
|
@@ -26402,7 +26417,10 @@ ${sg}${standardsBlock}${glossaryBlock}${buildGroundTruthBlock()}${sessionSliceBl
|
|
|
26402
26417
|
const lessonRelPath = `_content/${unitCode}/LESSON_${lessonCode}.md`;
|
|
26403
26418
|
const existingLessonContent = await storage.readArtifact(projectId, lessonRelPath);
|
|
26404
26419
|
let lessonContent = existingLessonContent || "";
|
|
26405
|
-
if (artifactScope.includes("LESSON") && (!existingLessonContent || force)) {
|
|
26420
|
+
if (artifactScope.includes("LESSON") && (!existingLessonContent || force || isStaleVsPlan(existingLessonContent))) {
|
|
26421
|
+
if (existingLessonContent && !force && isStaleVsPlan(existingLessonContent)) {
|
|
26422
|
+
onProgress?.("@content", `[STALENESS] LESSON_${lessonCode} was generated under a different plan_hash \u2014 regenerating against the current plan.`);
|
|
26423
|
+
}
|
|
26406
26424
|
onProgress?.("@content", `[1/4] Authoring Master Lesson Plan (${pedagogyLabel}): \`LESSON_${lessonCode}.md\` (${lessonTitle})...`);
|
|
26407
26425
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
26408
26426
|
const mediaDirective = options.mediaPolicy && options.mediaPolicy.maxGenImagesPerArtifact > 0 ? `
|
|
@@ -26473,7 +26491,7 @@ Fix ALL issues above and output the complete corrected document.` }],
|
|
|
26473
26491
|
} else {
|
|
26474
26492
|
lessonContent = lintReport.autoFixedContent || rawLesson;
|
|
26475
26493
|
}
|
|
26476
|
-
await storage.saveArtifact(projectId, lessonRelPath, lessonContent);
|
|
26494
|
+
await storage.saveArtifact(projectId, lessonRelPath, stampPlanHash(lessonContent));
|
|
26477
26495
|
producedArtifacts.push(`LESSON_${lessonCode}.md`);
|
|
26478
26496
|
}
|
|
26479
26497
|
const contentHash = lessonContent ? computeContentHash(lessonContent) : void 0;
|
|
@@ -26818,7 +26836,8 @@ ${lessonExcerpt}${symbolLedgerBlock}`;
|
|
|
26818
26836
|
});
|
|
26819
26837
|
};
|
|
26820
26838
|
const actRelPath = `_content/${unitCode}/ACT_${lessonCode}.md`;
|
|
26821
|
-
|
|
26839
|
+
const existingAct = await storage.readArtifact(projectId, actRelPath);
|
|
26840
|
+
if (artifactScope.includes("ACT") && (!existingAct || force || isStaleVsPlan(existingAct))) {
|
|
26822
26841
|
onProgress?.("@activity", `[2/4] Authoring Hands-on Lab: \`ACT_${lessonCode}.md\`...`);
|
|
26823
26842
|
const actDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
26824
26843
|
const actPrompt = `You are @activity (Lead Hands-on STEM & Laboratory Exercise Designer).
|
|
@@ -26878,7 +26897,7 @@ ${buildHeadingDirective("ACT", slcMarkdown, targetLang)}`;
|
|
|
26878
26897
|
rawError: rawAct || "Empty AI response"
|
|
26879
26898
|
});
|
|
26880
26899
|
}
|
|
26881
|
-
await storage.saveArtifact(projectId, actRelPath, rawAct);
|
|
26900
|
+
await storage.saveArtifact(projectId, actRelPath, stampPlanHash(rawAct));
|
|
26882
26901
|
await storage.updateArtifactState(projectId, lessonCode, "ACT", {
|
|
26883
26902
|
state: "completed",
|
|
26884
26903
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -26888,7 +26907,8 @@ ${buildHeadingDirective("ACT", slcMarkdown, targetLang)}`;
|
|
|
26888
26907
|
await judgeSat("ACT", rawAct);
|
|
26889
26908
|
}
|
|
26890
26909
|
const quizRelPath = `_content/${unitCode}/QUIZ_${lessonCode}.md`;
|
|
26891
|
-
|
|
26910
|
+
const existingQuiz = await storage.readArtifact(projectId, quizRelPath);
|
|
26911
|
+
if (artifactScope.includes("QUIZ") && (!existingQuiz || force || isStaleVsPlan(existingQuiz))) {
|
|
26892
26912
|
onProgress?.("@assessor", `[3/4] Authoring Assessment Bank: \`QUIZ_${lessonCode}.md\`...`);
|
|
26893
26913
|
const quizDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
26894
26914
|
const quizPrompt = `You are @assessor (Lead Psychometrician & Competency Assessment Specialist).
|
|
@@ -26942,7 +26962,7 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
26942
26962
|
rawError: rawQuiz || "Empty AI response"
|
|
26943
26963
|
});
|
|
26944
26964
|
}
|
|
26945
|
-
await storage.saveArtifact(projectId, quizRelPath, rawQuiz);
|
|
26965
|
+
await storage.saveArtifact(projectId, quizRelPath, stampPlanHash(rawQuiz));
|
|
26946
26966
|
await storage.updateArtifactState(projectId, lessonCode, "QUIZ", {
|
|
26947
26967
|
state: "completed",
|
|
26948
26968
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -26952,7 +26972,8 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
26952
26972
|
await judgeSat("QUIZ", rawQuiz);
|
|
26953
26973
|
}
|
|
26954
26974
|
const slideRelPath = `_content/${unitCode}/SLIDE_${lessonCode}.md`;
|
|
26955
|
-
|
|
26975
|
+
const existingSlide = await storage.readArtifact(projectId, slideRelPath);
|
|
26976
|
+
if (artifactScope.includes("SLIDE") && (!existingSlide || force || isStaleVsPlan(existingSlide))) {
|
|
26956
26977
|
onProgress?.("@illustrator", `[4/4] Authoring Presentation Slide Deck: \`SLIDE_${lessonCode}.md\`...`);
|
|
26957
26978
|
const isHtmlEngine = options.slidesEngine !== "marp";
|
|
26958
26979
|
if (isHtmlEngine) {
|
|
@@ -26986,7 +27007,7 @@ ${buildHeadingDirective("QUIZ", slcMarkdown, targetLang)}`;
|
|
|
26986
27007
|
let deckJson = workflowResult.deckJson;
|
|
26987
27008
|
const markdownWrapper = workflowResult.markdownWrapper;
|
|
26988
27009
|
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" }]};
|
|
26989
|
-
await storage.saveArtifact(projectId, slideRelPath, markdownWrapper);
|
|
27010
|
+
await storage.saveArtifact(projectId, slideRelPath, stampPlanHash(markdownWrapper));
|
|
26990
27011
|
producedArtifacts.push(`SLIDE_${lessonCode}.md`);
|
|
26991
27012
|
if (deckJson) {
|
|
26992
27013
|
const deckJsonStr = JSON.stringify(deckJson, null, 2);
|
|
@@ -27077,7 +27098,7 @@ footer: "Curriculum OS \u2022 ${lessonCode} (${pedagogyLabel})"
|
|
|
27077
27098
|
rawError: rawSlide || "Empty AI response"
|
|
27078
27099
|
});
|
|
27079
27100
|
}
|
|
27080
|
-
await storage.saveArtifact(projectId, slideRelPath, rawSlide);
|
|
27101
|
+
await storage.saveArtifact(projectId, slideRelPath, stampPlanHash(rawSlide));
|
|
27081
27102
|
await storage.updateArtifactState(projectId, lessonCode, "SLIDE", {
|
|
27082
27103
|
state: "completed",
|
|
27083
27104
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27088,7 +27109,8 @@ footer: "Curriculum OS \u2022 ${lessonCode} (${pedagogyLabel})"
|
|
|
27088
27109
|
}
|
|
27089
27110
|
}
|
|
27090
27111
|
const guideRelPath = `_content/${unitCode}/GUIDE_${lessonCode}.md`;
|
|
27091
|
-
|
|
27112
|
+
const existingGuide = await storage.readArtifact(projectId, guideRelPath);
|
|
27113
|
+
if (artifactScope.includes("GUIDE") && (!existingGuide || force || isStaleVsPlan(existingGuide))) {
|
|
27092
27114
|
onProgress?.("@content", `Authoring Teacher Guide: \`GUIDE_${lessonCode}.md\`...`, { artifactType: "GUIDE" });
|
|
27093
27115
|
const guideDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27094
27116
|
const guidePrompt = `You are @content (Senior Curriculum Developer & Teacher Facilitation Specialist).
|
|
@@ -27128,7 +27150,7 @@ ${buildHeadingDirective("GUIDE", slcMarkdown, targetLang)}`;
|
|
|
27128
27150
|
}
|
|
27129
27151
|
);
|
|
27130
27152
|
if (rawGuide && !rawGuide.startsWith("\u26A0\uFE0F") && rawGuide.length >= 200) {
|
|
27131
|
-
await storage.saveArtifact(projectId, guideRelPath, rawGuide);
|
|
27153
|
+
await storage.saveArtifact(projectId, guideRelPath, stampPlanHash(rawGuide));
|
|
27132
27154
|
await storage.updateArtifactState(projectId, lessonCode, "GUIDE", {
|
|
27133
27155
|
state: "completed",
|
|
27134
27156
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27139,7 +27161,8 @@ ${buildHeadingDirective("GUIDE", slcMarkdown, targetLang)}`;
|
|
|
27139
27161
|
}
|
|
27140
27162
|
}
|
|
27141
27163
|
const handoutRelPath = `_content/${unitCode}/HANDOUT_${lessonCode}.md`;
|
|
27142
|
-
|
|
27164
|
+
const existingHandout = await storage.readArtifact(projectId, handoutRelPath);
|
|
27165
|
+
if (artifactScope.includes("HANDOUT") && (!existingHandout || force || isStaleVsPlan(existingHandout))) {
|
|
27143
27166
|
onProgress?.("@content", `Authoring Student Handout: \`HANDOUT_${lessonCode}.md\`...`, { artifactType: "HANDOUT" });
|
|
27144
27167
|
const handoutDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27145
27168
|
const handoutPrompt = `You are @content (Educational Content Specialist).
|
|
@@ -27179,7 +27202,7 @@ ${buildHeadingDirective("HANDOUT", slcMarkdown, targetLang)}`;
|
|
|
27179
27202
|
}
|
|
27180
27203
|
);
|
|
27181
27204
|
if (rawHandout && !rawHandout.startsWith("\u26A0\uFE0F") && rawHandout.length >= 200) {
|
|
27182
|
-
await storage.saveArtifact(projectId, handoutRelPath, rawHandout);
|
|
27205
|
+
await storage.saveArtifact(projectId, handoutRelPath, stampPlanHash(rawHandout));
|
|
27183
27206
|
await storage.updateArtifactState(projectId, lessonCode, "HANDOUT", {
|
|
27184
27207
|
state: "completed",
|
|
27185
27208
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27190,7 +27213,8 @@ ${buildHeadingDirective("HANDOUT", slcMarkdown, targetLang)}`;
|
|
|
27190
27213
|
}
|
|
27191
27214
|
}
|
|
27192
27215
|
const wksRelPath = `_content/${unitCode}/WKS_${lessonCode}.md`;
|
|
27193
|
-
|
|
27216
|
+
const existingWks = await storage.readArtifact(projectId, wksRelPath);
|
|
27217
|
+
if (artifactScope.includes("WKS") && (!existingWks || force || isStaleVsPlan(existingWks))) {
|
|
27194
27218
|
onProgress?.("@content", `Authoring Student Worksheet: \`WKS_${lessonCode}.md\`...`, { artifactType: "WKS" });
|
|
27195
27219
|
const wksDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27196
27220
|
const wksPrompt = `You are @content (Instructional Activity & Worksheet Designer).
|
|
@@ -27234,7 +27258,7 @@ ${buildHeadingDirective("WKS", slcMarkdown, targetLang)}`;
|
|
|
27234
27258
|
}
|
|
27235
27259
|
);
|
|
27236
27260
|
if (rawWks && !rawWks.startsWith("\u26A0\uFE0F") && rawWks.length >= 200) {
|
|
27237
|
-
await storage.saveArtifact(projectId, wksRelPath, rawWks);
|
|
27261
|
+
await storage.saveArtifact(projectId, wksRelPath, stampPlanHash(rawWks));
|
|
27238
27262
|
await storage.updateArtifactState(projectId, lessonCode, "WKS", {
|
|
27239
27263
|
state: "completed",
|
|
27240
27264
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27245,7 +27269,8 @@ ${buildHeadingDirective("WKS", slcMarkdown, targetLang)}`;
|
|
|
27245
27269
|
}
|
|
27246
27270
|
}
|
|
27247
27271
|
const codeRelPath = `_content/${unitCode}/CODE_${lessonCode}.md`;
|
|
27248
|
-
|
|
27272
|
+
const existingCode = await storage.readArtifact(projectId, codeRelPath);
|
|
27273
|
+
if ((artifactScope.includes("CODE") || artifactScope.includes("CODE_LAB")) && (!existingCode || force || isStaleVsPlan(existingCode))) {
|
|
27249
27274
|
onProgress?.("@activity", `Authoring Executable Code Lab: \`CODE_${lessonCode}.md\`...`, { artifactType: "CODE" });
|
|
27250
27275
|
const codeDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27251
27276
|
const codePrompt = `You are @activity & @tech_sme (Lead Software Engineer & Technical SME).
|
|
@@ -27293,7 +27318,7 @@ ${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
|
|
|
27293
27318
|
}
|
|
27294
27319
|
);
|
|
27295
27320
|
if (rawCode && !rawCode.startsWith("\u26A0\uFE0F") && rawCode.length >= 200) {
|
|
27296
|
-
await storage.saveArtifact(projectId, codeRelPath, rawCode);
|
|
27321
|
+
await storage.saveArtifact(projectId, codeRelPath, stampPlanHash(rawCode));
|
|
27297
27322
|
await storage.updateArtifactState(projectId, lessonCode, "CODE", {
|
|
27298
27323
|
state: "completed",
|
|
27299
27324
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -27309,7 +27334,8 @@ ${buildHeadingDirective("CODE", slcMarkdown, targetLang)}`;
|
|
|
27309
27334
|
}
|
|
27310
27335
|
}
|
|
27311
27336
|
const extRelPath = `_content/${unitCode}/EXT_${lessonCode}.md`;
|
|
27312
|
-
|
|
27337
|
+
const existingExt = await storage.readArtifact(projectId, extRelPath);
|
|
27338
|
+
if (artifactScope.includes("EXT") && (!existingExt || force || isStaleVsPlan(existingExt))) {
|
|
27313
27339
|
onProgress?.("@activity", `Authoring Advanced Extension Challenge: \`EXT_${lessonCode}.md\`...`, { artifactType: "EXT" });
|
|
27314
27340
|
const extDateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
27315
27341
|
const isVi = targetLang === "vi";
|
|
@@ -27379,7 +27405,7 @@ ${buildHeadingDirective("EXT", slcMarkdown, targetLang)}`;
|
|
|
27379
27405
|
}
|
|
27380
27406
|
);
|
|
27381
27407
|
if (rawExt && !rawExt.startsWith("\u26A0\uFE0F") && rawExt.length >= 200) {
|
|
27382
|
-
await storage.saveArtifact(projectId, extRelPath, rawExt);
|
|
27408
|
+
await storage.saveArtifact(projectId, extRelPath, stampPlanHash(rawExt));
|
|
27383
27409
|
await storage.updateArtifactState(projectId, lessonCode, "EXT", {
|
|
27384
27410
|
state: "completed",
|
|
27385
27411
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|