@thanh01.pmt/curriculum-kit 1.4.45 → 1.4.46

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.
@@ -1,11 +1,11 @@
1
1
  import { MilestoneInput, LessonPlan, CurriculumQualityReport, ActivityLab, CodeLab, SelfLab, DiagnosticQuiz, SlideDeck, Handout, Worksheet, TeacherGuide, Extension, ProjectRoadmap } from '../schemas/index.cjs';
2
2
  import { M as ModelResolutionOptions } from '../provider-factory-Bv-eIkhg.cjs';
3
3
  import { G as GitPublishOptions, a as GitPublishResult, S as SupabasePublishOptions, b as SupabasePublishResult } from '../supabasePublisher-C627qXFT.cjs';
4
- import { S as SingleArtifactRequest, a as SingleArtifactResult } from '../gateSettings-oo5tCUS_.cjs';
5
- export { b as CurriculumArtifactType, C as CurriculumGateMode, D as DEFAULT_GATE_SETTINGS, G as GateSettings, R as ResolvedGateSettings, g as gateModeFor, p as parseGateSettings, r as resolveGateSettings } from '../gateSettings-oo5tCUS_.cjs';
4
+ import { S as SingleArtifactRequest, a as SingleArtifactResult } from '../gateSettings-JoqERuS1.cjs';
5
+ export { b as CurriculumArtifactType, C as CurriculumGateMode, D as DEFAULT_GATE_SETTINGS, G as GateSettings, R as ResolvedGateSettings, g as gateModeFor, p as parseGateSettings, r as resolveGateSettings } from '../gateSettings-JoqERuS1.cjs';
6
6
  import * as workflow from 'workflow';
7
7
  import { z } from 'zod';
8
- import { F as FrameworkPack, C as CoverageGateReport } from '../standardsCoverageGate-CLnq0d0s.cjs';
8
+ import { F as FrameworkPack, C as CoverageGateReport } from '../standardsCoverageGate-49pJq5t8.cjs';
9
9
  import 'ai';
10
10
 
11
11
  interface GenerateMasterLessonStepInput {
@@ -1,11 +1,11 @@
1
1
  import { MilestoneInput, LessonPlan, CurriculumQualityReport, ActivityLab, CodeLab, SelfLab, DiagnosticQuiz, SlideDeck, Handout, Worksheet, TeacherGuide, Extension, ProjectRoadmap } from '../schemas/index.js';
2
2
  import { M as ModelResolutionOptions } from '../provider-factory-Bv-eIkhg.js';
3
3
  import { G as GitPublishOptions, a as GitPublishResult, S as SupabasePublishOptions, b as SupabasePublishResult } from '../supabasePublisher-C627qXFT.js';
4
- import { S as SingleArtifactRequest, a as SingleArtifactResult } from '../gateSettings-oo5tCUS_.js';
5
- export { b as CurriculumArtifactType, C as CurriculumGateMode, D as DEFAULT_GATE_SETTINGS, G as GateSettings, R as ResolvedGateSettings, g as gateModeFor, p as parseGateSettings, r as resolveGateSettings } from '../gateSettings-oo5tCUS_.js';
4
+ import { S as SingleArtifactRequest, a as SingleArtifactResult } from '../gateSettings-JoqERuS1.js';
5
+ export { b as CurriculumArtifactType, C as CurriculumGateMode, D as DEFAULT_GATE_SETTINGS, G as GateSettings, R as ResolvedGateSettings, g as gateModeFor, p as parseGateSettings, r as resolveGateSettings } from '../gateSettings-JoqERuS1.js';
6
6
  import * as workflow from 'workflow';
7
7
  import { z } from 'zod';
8
- import { F as FrameworkPack, C as CoverageGateReport } from '../standardsCoverageGate-CLnq0d0s.js';
8
+ import { F as FrameworkPack, C as CoverageGateReport } from '../standardsCoverageGate-49pJq5t8.js';
9
9
  import 'ai';
10
10
 
11
11
  interface GenerateMasterLessonStepInput {
@@ -18636,17 +18636,6 @@ function buildLanguageDirective(targetLanguage) {
18636
18636
  ${exampleLine}` : ""}
18637
18637
  - CJK / NON-LATIN SCRIPT BAN (ABSOLUTE): NEVER output characters from Chinese (\u6C49\u5B57), Japanese (\u304B\u306A/\u6F22\u5B57), or Korean (\uD55C\uAE00) scripts ANYWHERE in the document \u2014 not even a single glyph spliced inside a ${name} sentence. Observed past violations that are STRICTLY forbidden: \u6392\u67E5, \u5305\u542B, \u5BFC\u81F4, \u662F\u591A\u5C11, \u6280\u672F, \u771F\u673A, \u4F11\u606F, \u7EB8\u8D28. To express such meaning write it fully in ${name} or keep the ENGLISH technical term (e.g. write "t\u1EF1 ki\u1EC3m tra l\u1ED7i" / "self-debugging", "bao g\u1ED3m" / "includes"). A mechanical scanner rejects any document containing even one CJK character.`;
18638
18638
  }
18639
- function matchesArtifactType(candidate, target) {
18640
- const c = candidate.trim().toUpperCase();
18641
- const t = target.trim().toUpperCase();
18642
- if (c === t) return true;
18643
- if (c.startsWith("LESSON") && t.startsWith("LESSON")) return true;
18644
- if ((c === "CODE" || c === "CODE_LAB") && (t === "CODE" || t === "CODE_LAB")) return true;
18645
- if ((c === "EXPOSITION" || c === "KNOWLEDGE_EXPOSITION") && (t === "EXPOSITION" || t === "KNOWLEDGE_EXPOSITION")) return true;
18646
- if ((c === "WKS" || c === "WORKSHEET") && (t === "WKS" || t === "WORKSHEET")) return true;
18647
- if ((c === "EXT" || c === "EXTENSION") && (t === "EXT" || t === "EXTENSION")) return true;
18648
- return false;
18649
- }
18650
18639
  var TEMPLATE_BY_TYPE = {
18651
18640
  LESSON: "LESSON_5E_template.md",
18652
18641
  LESSON_5E: "LESSON_5E_template.md",
@@ -18655,7 +18644,7 @@ var TEMPLATE_BY_TYPE = {
18655
18644
  ACT: "ACT_template.md",
18656
18645
  CODE: "CODE_template.md",
18657
18646
  // JSON-first code lab shares the CODE label set (the serializer renders its
18658
- // own headings; this lookup only feeds the SLC/directive fallback path).
18647
+ // own headings; this lookup only feeds the directive fallback path).
18659
18648
  CODE_LAB: "CODE_template.md",
18660
18649
  QUIZ: "QUIZ_v4.6_template.md",
18661
18650
  GUIDE: "GUIDE_template.md",
@@ -18667,87 +18656,21 @@ var TEMPLATE_BY_TYPE = {
18667
18656
  LEARNER_PROFILE: "LEARNER_PROFILE_template.md",
18668
18657
  PROJECT_BRIEF: "PROJECT_BRIEF_template.md",
18669
18658
  CURRICULUM_FRAMEWORK: "CURRICULUM_FRAMEWORK_template.md",
18670
- CONTENT_STYLE_GUIDE: "CONTENT_STYLE_GUIDE_template.md",
18671
- SECTION_LANGUAGE_CONTRACT: "SECTION_LANGUAGE_CONTRACT_template.md"
18659
+ CONTENT_STYLE_GUIDE: "CONTENT_STYLE_GUIDE_template.md"
18672
18660
  };
18673
- function keepContractEntries(artifactType, mapping) {
18661
+ function extractSectionHeadings(artifactType, opts) {
18674
18662
  const templateFile = TEMPLATE_BY_TYPE[artifactType.trim().toUpperCase()];
18675
- if (!templateFile) return mapping;
18663
+ if (!templateFile) return {};
18676
18664
  const resolved = resolveArtifactTemplate(templateFile);
18677
- if (!resolved) return mapping;
18678
- const contract = new Set(resolved.sections.map(stripHeadingKey));
18679
- const kept = {};
18680
- for (const [k, v] of Object.entries(mapping)) {
18681
- if (contract.has(stripHeadingKey(k))) kept[k] = v;
18682
- }
18683
- return kept;
18665
+ if (!resolved) return {};
18666
+ return Object.fromEntries(resolved.sections.map((s) => [s, s]));
18684
18667
  }
18685
- function extractSectionHeadingsFromSLC(slcInput, artifactType, targetLanguage = "vi") {
18686
- const upperType = artifactType.trim().toUpperCase();
18687
- const getFallback = () => {
18688
- const templateFile = TEMPLATE_BY_TYPE[upperType];
18689
- if (!templateFile) return {};
18690
- const resolved = resolveArtifactTemplate(templateFile);
18691
- if (!resolved) return {};
18692
- return Object.fromEntries(resolved.sections.map((s) => [s, s]));
18693
- };
18694
- if (!slcInput) return getFallback();
18695
- if (typeof slcInput === "object") {
18696
- if (slcInput[upperType] && Object.keys(slcInput[upperType]).length > 0) {
18697
- return keepContractEntries(upperType, slcInput[upperType]);
18698
- }
18699
- for (const [key, mapping] of Object.entries(slcInput)) {
18700
- if (matchesArtifactType(key, upperType) && Object.keys(mapping).length > 0) {
18701
- return keepContractEntries(upperType, mapping);
18702
- }
18703
- }
18704
- return getFallback();
18705
- }
18706
- const slcMarkdown = slcInput;
18707
- const blocks = slcMarkdown.split(/\n(?=#{2,3}\s+[A-Z0-9_]+)/g);
18708
- for (const block of blocks) {
18709
- const headerMatch = block.match(/^#{2,3}\s+([A-Z0-9_]+)/);
18710
- if (!headerMatch) continue;
18711
- const blockType = headerMatch[1].trim().toUpperCase();
18712
- if (matchesArtifactType(blockType, upperType)) {
18713
- const mapping = {};
18714
- const lines = block.split("\n");
18715
- for (const line of lines) {
18716
- const trimmed = line.trim();
18717
- if (trimmed.startsWith("|") && !trimmed.includes("---")) {
18718
- const cells = trimmed.split("|").map((c) => c.trim()).filter((_, idx, arr) => idx > 0 && idx < arr.length - 1);
18719
- if (cells.length >= 2 && !cells[0].toLowerCase().includes("canonical") && !cells[1].toLowerCase().includes("localized")) {
18720
- mapping[cells[0]] = cells[1];
18721
- }
18722
- } else {
18723
- const bullet = line.match(/^[-*]\s+([^:]+):\s+(.+)$/);
18724
- if (bullet) {
18725
- mapping[bullet[1].trim()] = bullet[2].trim();
18726
- }
18727
- }
18728
- }
18729
- if (Object.keys(mapping).length > 0) return keepContractEntries(upperType, mapping);
18730
- }
18731
- }
18732
- return getFallback();
18733
- }
18734
- function buildHeadingDirective(artifactType, slcMarkdown, targetLanguage = "vi", opts) {
18735
- const upperType = artifactType.trim().toUpperCase();
18736
- const templateFile = TEMPLATE_BY_TYPE[upperType];
18737
- const resolved = templateFile ? resolveArtifactTemplate(templateFile) : null;
18738
- const baked = !!resolved && resolved.declaredLang !== "en";
18739
- const headings = resolved ? Object.fromEntries(
18740
- resolved.sections.map((s) => [
18741
- s,
18742
- baked ? s : extractSectionHeadingsFromSLC(slcMarkdown, upperType, targetLanguage)[s] || s
18743
- ])
18744
- ) : extractSectionHeadingsFromSLC(baked ? null : slcMarkdown, upperType, targetLanguage);
18668
+ function buildHeadingDirective(artifactType, opts) {
18669
+ const headings = extractSectionHeadings(artifactType);
18745
18670
  if (Object.keys(headings).length === 0) {
18746
18671
  return "";
18747
18672
  }
18748
- const lines = Object.entries(headings).map(
18749
- ([heading, display]) => heading === display ? ` - "${display}"` : ` - "${heading}" -> Use Display Heading: "${display}"`
18750
- );
18673
+ const lines = Object.keys(headings).map((heading) => ` - "${heading}"`);
18751
18674
  return `MANDATORY SECTION HEADINGS (SOURCE: RESOLVED ARTIFACT TEMPLATE):
18752
18675
  - Copy the template's YAML frontmatter \`template_required_sections\` list VERBATIM into the artifact frontmatter \u2014 never translate, reorder, or invent entries.
18753
18676
  - In the markdown body, section headers MUST be exactly the Display Headings below (do NOT translate, paraphrase, or re-marker them):
@@ -19066,9 +18989,8 @@ function buildSectionAwareExcerpt(markdown, opts = {}) {
19066
18989
  };
19067
18990
  }
19068
18991
  const minContentChars = opts.minContentChars !== void 0 ? opts.minContentChars : Math.min(400, source.length);
19069
- const slcMap = normalizeSlcContract(opts.sectionLanguageContract);
19070
18992
  const effectiveArtifactType = opts.artifactType || deriveArtifactTypeFromFileName(opts.fileName);
19071
- const sections = parseMarkdownSections(source, slcMap, effectiveArtifactType);
18993
+ const sections = parseMarkdownSections(source);
19072
18994
  const metaBlock = buildMetaBlock(source, effectiveArtifactType);
19073
18995
  if (sections.length === 0) {
19074
18996
  issues.push("parse:no-sections");
@@ -19191,48 +19113,16 @@ function buildLessonExcerpt(markdown, opts = {}) {
19191
19113
  priorities: DEFAULT_LESSON_PRIORITIES
19192
19114
  });
19193
19115
  }
19194
- function normalizeSlcContract(slc) {
19195
- if (!slc) return void 0;
19196
- if (typeof slc !== "string") return slc;
19197
- const out = {};
19198
- const blocks = slc.split(/\n(?=#{2,3}\s+[A-Z0-9_]+)/g);
19199
- for (const block of blocks) {
19200
- const header = block.match(/^#{2,3}\s+([A-Z0-9_]+)/);
19201
- if (!header?.[1]) continue;
19202
- const mapping = {};
19203
- for (const line of block.split("\n")) {
19204
- const t = line.trim();
19205
- if (!t.startsWith("|") || t.includes("---")) continue;
19206
- const cells = t.split("|").map((c) => c.trim()).filter((_, i, a) => i > 0 && i < a.length - 1);
19207
- const [c0, c1] = cells;
19208
- if (c0 && c1 && !c0.toLowerCase().includes("canonical") && !c1.toLowerCase().includes("localized")) {
19209
- mapping[c0] = c1;
19210
- }
19211
- }
19212
- if (Object.keys(mapping).length > 0) out[header[1]] = mapping;
19213
- }
19214
- return Object.keys(out).length > 0 ? out : void 0;
19215
- }
19216
- function parseMarkdownSections(markdown, slcMap, artifactType) {
19116
+ function parseMarkdownSections(markdown) {
19217
19117
  const sections = [];
19218
19118
  const lines = markdown.split("\n");
19219
19119
  let currentHeading = "";
19220
19120
  let currentBody = [];
19221
- const reverseMap = /* @__PURE__ */ new Map();
19222
- if (slcMap) {
19223
- const maps = artifactType && slcMap[artifactType] ? [slcMap[artifactType]] : Object.values(slcMap);
19224
- for (const m of maps) {
19225
- for (const [canonical, localized] of Object.entries(m)) {
19226
- reverseMap.set(normalizeHeading(localized), canonical);
19227
- reverseMap.set(normalizeHeading(canonical), canonical);
19228
- }
19229
- }
19230
- }
19231
19121
  const flush = () => {
19232
19122
  if (!currentHeading) return;
19233
19123
  const cleanTitle = currentHeading.replace(/^#{1,4}\s+/, "").trim();
19234
19124
  const norm = normalizeHeading(cleanTitle);
19235
- const canonicalKey = reverseMap.get(norm) || findCanonicalFuzzy(norm);
19125
+ const canonicalKey = findCanonicalFuzzy(norm);
19236
19126
  sections.push({
19237
19127
  rawHeading: currentHeading,
19238
19128
  cleanTitle,
@@ -19331,7 +19221,7 @@ function buildMetaBlock(source, artifactType) {
19331
19221
  function deriveArtifactTypeFromFileName(fileName) {
19332
19222
  if (!fileName) return void 0;
19333
19223
  const base = fileName.replace(/\.md$/i, "");
19334
- const multiWord = base.match(/^(KNOWLEDGE_EXPOSITION|SECTION_LANGUAGE_CONTRACT|CONTENT_STYLE_GUIDE|CURRICULUM_FRAMEWORK|LEARNER_PROFILE|PROJECT_BRIEF|REFERENCE_PACK|CURRICULUM_PLAN)/i);
19224
+ const multiWord = base.match(/^(KNOWLEDGE_EXPOSITION|CONTENT_STYLE_GUIDE|CURRICULUM_FRAMEWORK|LEARNER_PROFILE|PROJECT_BRIEF|REFERENCE_PACK|CURRICULUM_PLAN)/i);
19335
19225
  if (multiWord) return multiWord[1].toUpperCase();
19336
19226
  const token = base.match(/^([A-Z][A-Z0-9_]*?)(?=_|$)/);
19337
19227
  return token ? token[1] : void 0;
@@ -19568,11 +19458,7 @@ async function generateSingleArtifact(req) {
19568
19458
  language.toLowerCase().includes("bilingual") || language.toLowerCase().includes("song");
19569
19459
  const targetLang = resolveTargetLanguageCode(language);
19570
19460
  const langDirective = buildLanguageDirective(language);
19571
- const headingDirective = buildHeadingDirective(
19572
- artifactType.toUpperCase(),
19573
- req.sectionLanguageContract,
19574
- targetLang
19575
- );
19461
+ const headingDirective = buildHeadingDirective(artifactType.toUpperCase());
19576
19462
  const availableSources = {
19577
19463
  KNOWLEDGE_EXPOSITION: contextSot.exposition || researchContext,
19578
19464
  CANONICAL_LESSON: contextSot.lessonPlan,
@@ -19639,11 +19525,10 @@ ${symbolLedgerPrompt}
19639
19525
 
19640
19526
  IMAGE PLANNING (media ledger) \u2014 QUOTA GEN: t\u1ED1i \u0111a ${mediaPolicy.maxGenImagesPerArtifact} \u1EA3nh AI cho artifact n\xE0y (\u1EA3nh search kho kh\xF4ng gi\u1EDBi h\u1EA1n).
19641
19527
  Khi n\u1ED9i dung c\u1EA7n minh h\u1ECDa (diagram quy tr\xECnh, s\u01A1 \u0111\u1ED3 kh\xE1i ni\u1EC7m, step-by-step visual), ch\xE8n placeholder \u0111\xFAng format [IMAGE: slug] (slug ch\u1EEF th\u01B0\u1EDDng-g\u1EA1ch ngang, unique trong b\xE0i, vd img-for-loop-diagram) T\u1EA0I \u0110\xDANG CH\u1ED6 c\u1EA7n \u1EA3nh, tr\xEAn d\xF2ng ri\xEAng. KH\xD4NG t\u1EF1 sinh \u1EA3nh, KH\xD4NG d\xF9ng markdown image \u2014 placeholder s\u1EBD \u0111\u01B0\u1EE3c thay b\u1EB1ng \u1EA3nh th\u1EADt sau khi Media Curator duy\u1EC7t. Ch\u1EC9 \u0111\u1EB7t cho \u1EA3nh TH\u1EF0C S\u1EF0 c\u1EA7n thi\u1EBFt.` : ""}`;
19642
- const slcContract = req.sectionLanguageContract;
19643
- const frameworkExcerpt = contextSot.framework ? buildSectionAwareExcerpt(contextSot.framework, { budget: 2500, sectionLanguageContract: slcContract }).excerpt : "";
19644
- const lessonPlanExcerpt = contextSot.lessonPlan ? buildLessonExcerpt(contextSot.lessonPlan, { budget: 8e3, sectionLanguageContract: slcContract, artifactType: "LESSON" }).excerpt : "";
19645
- const handoutExcerpt = contextSot.handout ? buildSectionAwareExcerpt(contextSot.handout, { budget: 2e3, sectionLanguageContract: slcContract }).excerpt : "";
19646
- const expositionExcerpt = contextSot.exposition ? buildExpositionExcerpt(contextSot.exposition, { budget: 6e3, sectionLanguageContract: slcContract }).excerpt : "";
19528
+ const frameworkExcerpt = contextSot.framework ? buildSectionAwareExcerpt(contextSot.framework, { budget: 2500 }).excerpt : "";
19529
+ const lessonPlanExcerpt = contextSot.lessonPlan ? buildLessonExcerpt(contextSot.lessonPlan, { budget: 8e3, artifactType: "LESSON" }).excerpt : "";
19530
+ const handoutExcerpt = contextSot.handout ? buildSectionAwareExcerpt(contextSot.handout, { budget: 2e3 }).excerpt : "";
19531
+ const expositionExcerpt = contextSot.exposition ? buildExpositionExcerpt(contextSot.exposition, { budget: 6e3 }).excerpt : "";
19647
19532
  const userPrompt = `### CONTEXT GROUND TRUTH:
19648
19533
  - Topic / Concept Domain: "${topic}"
19649
19534
  - Lesson ID: "${lessonId || "ON_DEMAND"}"