@thanh01.pmt/curriculum-kit 1.4.43 → 1.4.45
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/ai/index.cjs +66 -470
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +77 -77
- package/dist/ai/index.d.ts +77 -77
- package/dist/ai/index.mjs +64 -469
- package/dist/ai/index.mjs.map +1 -1
- package/dist/index.cjs +478 -837
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -58
- package/dist/index.d.ts +124 -58
- package/dist/index.mjs +470 -829
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +99 -484
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +97 -483
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/schemas/index.d.cts +1064 -1064
- package/dist/schemas/index.d.ts +1064 -1064
- package/dist/standards/index.d.cts +2 -2
- package/dist/standards/index.d.ts +2 -2
- package/dist/{standardsCoverageGate-49pJq5t8.d.cts → standardsCoverageGate-CLnq0d0s.d.cts} +12 -12
- package/dist/{standardsCoverageGate-49pJq5t8.d.ts → standardsCoverageGate-CLnq0d0s.d.ts} +12 -12
- package/dist/templates/ACT_template.md +18 -9
- package/dist/templates/ALIGNMENT_MATRIX_template.md +5 -0
- package/dist/templates/ART_DIRECTION_template.md +7 -0
- package/dist/templates/ASSET_MANIFEST_template.md +5 -0
- package/dist/templates/BASELINE_STANDARD.md +5 -0
- package/dist/templates/BELL_RINGER_template.md +13 -13
- package/dist/templates/CHANGELOG_template.md +3 -0
- package/dist/templates/CHOICE_BOARD_template.md +8 -5
- package/dist/templates/CODE_template.md +5 -6
- package/dist/templates/CONTENT_CONTINUITY_template.md +6 -0
- package/dist/templates/CONTENT_STYLE_GUIDE_template.md +4 -5
- package/dist/templates/CURRICULUM_FRAMEWORK_template.md +5 -6
- package/dist/templates/DEPENDENCY_MAP_template.md +3 -4
- package/dist/templates/EXIT_TICKET_template.md +8 -8
- package/dist/templates/EXT_template.md +3 -0
- package/dist/templates/GLOSSARY_template.md +1 -2
- package/dist/templates/GRAPHIC_ORGANIZER_template.md +8 -8
- package/dist/templates/GUIDE_template.md +5 -6
- package/dist/templates/HANDOUT_template.md +5 -6
- package/dist/templates/HANDOVER_DOCUMENT_template.md +8 -0
- package/dist/templates/KNOWLEDGE_EXPOSITION_template.md +16 -6
- package/dist/templates/LAB_TEMPLATE.md +78 -0
- package/dist/templates/LEARNER_PROFILE_template.md +4 -5
- package/dist/templates/LESSONS_LEARNED_template.md +8 -0
- package/dist/templates/LESSON_5E_template.md +24 -9
- package/dist/templates/LESSON_EDP_template.md +26 -10
- package/dist/templates/LESSON_GENERAL_template.md +22 -8
- package/dist/templates/OUTPUT_CONSTRAINTS_template.md +7 -0
- package/dist/templates/PACKAGING_SPEC_template.md +8 -0
- package/dist/templates/PILOT_FEEDBACK_template.md +6 -0
- package/dist/templates/PROJECT_BRIEF_template.md +8 -0
- package/dist/templates/PROJECT_STATUS_template.md +9 -0
- package/dist/templates/QUIZ_template.md +7 -0
- package/dist/templates/QUIZ_v4.6_template.md +4 -5
- package/dist/templates/REFERENCE_PACK_template.md +4 -0
- package/dist/templates/REVIEW_GAME_template.md +11 -8
- package/dist/templates/RUBRIC_template.md +2 -3
- package/dist/templates/SCIENCE_LAB_template.md +11 -5
- package/dist/templates/SECTION_LANGUAGE_CONTRACT_template.md +44 -0
- package/dist/templates/SELF_LAB_template.md +174 -0
- package/dist/templates/SLIDE_template.md +23 -0
- package/dist/templates/STATION_ROTATION_template.md +11 -11
- package/dist/templates/TASK_CARDS_template.md +8 -8
- package/dist/templates/TIERED_PRACTICE_template.md +14 -10
- package/dist/templates/UPDATE_ROADMAP_template.md +7 -0
- package/dist/templates/WKS_template.md +5 -6
- package/dist/workflow/index.cjs +250 -672
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.d.cts +1 -1
- package/dist/workflow/index.d.ts +1 -1
- package/dist/workflow/index.mjs +248 -670
- package/dist/workflow/index.mjs.map +1 -1
- package/docs/refs/templates/ACT_template.md +18 -9
- package/docs/refs/templates/ALIGNMENT_MATRIX_template.md +5 -0
- package/docs/refs/templates/ART_DIRECTION_template.md +7 -0
- package/docs/refs/templates/ASSET_MANIFEST_template.md +5 -0
- package/docs/refs/templates/BASELINE_STANDARD.md +5 -0
- package/docs/refs/templates/BELL_RINGER_template.md +13 -13
- package/docs/refs/templates/CHANGELOG_template.md +3 -0
- package/docs/refs/templates/CHOICE_BOARD_template.md +8 -5
- package/docs/refs/templates/CODE_template.md +5 -6
- package/docs/refs/templates/CONTENT_CONTINUITY_template.md +6 -0
- package/docs/refs/templates/CONTENT_STYLE_GUIDE_template.md +4 -5
- package/docs/refs/templates/CURRICULUM_FRAMEWORK_template.md +5 -6
- package/docs/refs/templates/DEPENDENCY_MAP_template.md +3 -4
- package/docs/refs/templates/EXIT_TICKET_template.md +8 -8
- package/docs/refs/templates/EXT_template.md +3 -0
- package/docs/refs/templates/GLOSSARY_template.md +1 -2
- package/docs/refs/templates/GRAPHIC_ORGANIZER_template.md +8 -8
- package/docs/refs/templates/GUIDE_template.md +5 -6
- package/docs/refs/templates/HANDOUT_template.md +5 -6
- package/docs/refs/templates/HANDOVER_DOCUMENT_template.md +8 -0
- package/docs/refs/templates/KNOWLEDGE_EXPOSITION_template.md +16 -6
- package/docs/refs/templates/LAB_TEMPLATE.md +78 -0
- package/docs/refs/templates/LEARNER_PROFILE_template.md +4 -5
- package/docs/refs/templates/LESSONS_LEARNED_template.md +8 -0
- package/docs/refs/templates/LESSON_5E_template.md +24 -9
- package/docs/refs/templates/LESSON_EDP_template.md +26 -10
- package/docs/refs/templates/LESSON_GENERAL_template.md +22 -8
- package/docs/refs/templates/OUTPUT_CONSTRAINTS_template.md +7 -0
- package/docs/refs/templates/PACKAGING_SPEC_template.md +8 -0
- package/docs/refs/templates/PILOT_FEEDBACK_template.md +6 -0
- package/docs/refs/templates/PROJECT_BRIEF_template.md +8 -0
- package/docs/refs/templates/PROJECT_STATUS_template.md +9 -0
- package/docs/refs/templates/QUIZ_template.md +7 -0
- package/docs/refs/templates/QUIZ_v4.6_template.md +4 -5
- package/docs/refs/templates/REFERENCE_PACK_template.md +4 -0
- package/docs/refs/templates/REVIEW_GAME_template.md +11 -8
- package/docs/refs/templates/RUBRIC_template.md +2 -3
- package/docs/refs/templates/SCIENCE_LAB_template.md +11 -5
- package/docs/refs/templates/SECTION_LANGUAGE_CONTRACT_template.md +44 -0
- package/docs/refs/templates/SELF_LAB_template.md +174 -0
- package/docs/refs/templates/SLIDE_template.md +23 -0
- package/docs/refs/templates/STATION_ROTATION_template.md +11 -11
- package/docs/refs/templates/TASK_CARDS_template.md +8 -8
- package/docs/refs/templates/TIERED_PRACTICE_template.md +14 -10
- package/docs/refs/templates/UPDATE_ROADMAP_template.md +7 -0
- package/docs/refs/templates/WKS_template.md +5 -6
- package/package.json +1 -1
package/dist/workflow/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs2 from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
4
4
|
import { createOpenAI } from '@ai-sdk/openai';
|
|
5
5
|
import { createDeepSeek } from '@ai-sdk/deepseek';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
6
7
|
import { generateObject } from 'ai';
|
|
7
8
|
import { z } from 'zod';
|
|
8
9
|
import { defineHook, getStepMetadata, RetryableError, sleep } from 'workflow';
|
|
9
|
-
import
|
|
10
|
+
import fs3 from 'fs/promises';
|
|
10
11
|
import { Octokit } from '@octokit/rest';
|
|
11
12
|
import { createClient } from '@supabase/supabase-js';
|
|
12
13
|
import 'crypto';
|
|
13
|
-
import { fileURLToPath } from 'url';
|
|
14
14
|
|
|
15
15
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
16
16
|
var __esm = (fn, res) => function __init() {
|
|
@@ -151,8 +151,8 @@ function resolveApiKey(keyName, explicitKey) {
|
|
|
151
151
|
path.resolve(currentDir, "../..", ".env")
|
|
152
152
|
];
|
|
153
153
|
for (const envPath of envPaths) {
|
|
154
|
-
if (
|
|
155
|
-
const content =
|
|
154
|
+
if (fs2.existsSync(envPath)) {
|
|
155
|
+
const content = fs2.readFileSync(envPath, "utf-8");
|
|
156
156
|
for (const line of content.split("\n")) {
|
|
157
157
|
const trimmed = line.trim();
|
|
158
158
|
if (trimmed && !trimmed.startsWith("#") && trimmed.startsWith(keyName + "=")) {
|
|
@@ -1127,10 +1127,138 @@ var init_provider_factory = __esm({
|
|
|
1127
1127
|
};
|
|
1128
1128
|
}
|
|
1129
1129
|
});
|
|
1130
|
+
function stripTemplateFrontmatter(raw) {
|
|
1131
|
+
let body = raw;
|
|
1132
|
+
if (body.startsWith("---")) {
|
|
1133
|
+
const end = body.indexOf("\n---", 3);
|
|
1134
|
+
if (end !== -1) body = body.slice(end + 4);
|
|
1135
|
+
}
|
|
1136
|
+
return body.split("\n").filter((l) => l.trim() !== "<!-- INJECT_BODY -->").join("\n").replace(/^\s*\n/, "").trimEnd();
|
|
1137
|
+
}
|
|
1138
|
+
function stripHeadingKey(h) {
|
|
1139
|
+
return h.replace(/\[(REQUIRED|OPTIONAL|CONDITIONAL)\]\s*/gi, "").replace(/^\s*\d+[.)]\s+/, "").replace(/\s+/g, " ").trim();
|
|
1140
|
+
}
|
|
1141
|
+
function isVariableHeading(text) {
|
|
1142
|
+
return /\{\{[^}]*\}\}/.test(text) || /\[[^\]]+\]/.test(text);
|
|
1143
|
+
}
|
|
1144
|
+
function collectHeadings(body) {
|
|
1145
|
+
const out = [];
|
|
1146
|
+
let inFence = false;
|
|
1147
|
+
for (const line of body.split("\n")) {
|
|
1148
|
+
if (/^(```|~~~)/.test(line.trim())) {
|
|
1149
|
+
inFence = !inFence;
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
if (inFence) continue;
|
|
1153
|
+
const m = line.match(/^(#{2,3})\s+(.*)$/);
|
|
1154
|
+
if (!m) continue;
|
|
1155
|
+
const text = m[2].trim();
|
|
1156
|
+
const optional = /^\[OPTIONAL\]/i.test(text);
|
|
1157
|
+
const name = stripHeadingKey(text);
|
|
1158
|
+
if (!name || isVariableHeading(name)) continue;
|
|
1159
|
+
out.push({ level: m[1].length, name, optional });
|
|
1160
|
+
}
|
|
1161
|
+
return out;
|
|
1162
|
+
}
|
|
1163
|
+
function extractEchoSections(raw) {
|
|
1164
|
+
const hs = collectHeadings(stripTemplateFrontmatter(raw));
|
|
1165
|
+
return {
|
|
1166
|
+
required: hs.filter((h) => !h.optional).map((h) => h.name),
|
|
1167
|
+
optional: hs.filter((h) => h.optional).map((h) => h.name)
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
function extractConditionalSections(raw) {
|
|
1171
|
+
const body = stripTemplateFrontmatter(raw);
|
|
1172
|
+
return body.split("\n").filter((l) => /^#{2,3} .*\[CONDITIONAL\]/i.test(l)).map((l) => stripHeadingKey(l.replace(/^#{2,3}\s*/, "").trim())).filter((s) => s.length > 0 && !isVariableHeading(s));
|
|
1173
|
+
}
|
|
1174
|
+
function extractDeclaredLanguage(raw) {
|
|
1175
|
+
const m = raw.match(/^template_language:\s*["']?([a-zA-Z-]+)["']?\s*$/m);
|
|
1176
|
+
return m?.[1]?.toLowerCase() || "en";
|
|
1177
|
+
}
|
|
1178
|
+
function candidateDirs(explicitDir) {
|
|
1179
|
+
const dirs = [];
|
|
1180
|
+
if (process.env.CURRICULUM_TEMPLATES_DIR) dirs.push(process.env.CURRICULUM_TEMPLATES_DIR);
|
|
1181
|
+
dirs.push(path.resolve(process.cwd(), "_templates"));
|
|
1182
|
+
for (const rel of KIT_TEMPLATE_FALLBACK_DIRS) {
|
|
1183
|
+
dirs.push(path.resolve(_moduleDir, rel));
|
|
1184
|
+
dirs.push(path.resolve(process.cwd(), rel));
|
|
1185
|
+
dirs.push(path.resolve(process.cwd(), "packages/curriculum-kit", rel));
|
|
1186
|
+
}
|
|
1187
|
+
return dirs;
|
|
1188
|
+
}
|
|
1189
|
+
function findTemplatePath(templateName, explicitDir) {
|
|
1190
|
+
for (const dir of candidateDirs()) {
|
|
1191
|
+
const p = path.join(dir, templateName);
|
|
1192
|
+
if (!fs2.existsSync(p)) continue;
|
|
1193
|
+
try {
|
|
1194
|
+
fs2.accessSync(p, fs2.constants.R_OK);
|
|
1195
|
+
return p;
|
|
1196
|
+
} catch {
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
return null;
|
|
1200
|
+
}
|
|
1201
|
+
function resolveArtifactTemplate(templateName, opts) {
|
|
1202
|
+
const p = findTemplatePath(templateName);
|
|
1203
|
+
if (!p) return null;
|
|
1204
|
+
try {
|
|
1205
|
+
const raw = fs2.readFileSync(p, "utf-8");
|
|
1206
|
+
const echo = extractEchoSections(raw);
|
|
1207
|
+
return {
|
|
1208
|
+
content: stripTemplateFrontmatter(raw),
|
|
1209
|
+
sections: echo.required,
|
|
1210
|
+
optionalSections: echo.optional,
|
|
1211
|
+
sourcePath: p,
|
|
1212
|
+
conditionals: extractConditionalSections(raw),
|
|
1213
|
+
declaredLang: extractDeclaredLanguage(raw)
|
|
1214
|
+
};
|
|
1215
|
+
} catch {
|
|
1216
|
+
return null;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function loadCurriculumTemplate(templateName, templatesDir) {
|
|
1220
|
+
const p = findTemplatePath(templateName);
|
|
1221
|
+
if (!p) return "";
|
|
1222
|
+
try {
|
|
1223
|
+
return fs2.readFileSync(p, "utf-8");
|
|
1224
|
+
} catch {
|
|
1225
|
+
return "";
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
function loadAuthoringTemplate(templateName, templatesDir) {
|
|
1229
|
+
const p = findTemplatePath(templateName);
|
|
1230
|
+
if (!p) return "";
|
|
1231
|
+
try {
|
|
1232
|
+
return stripTemplateFrontmatter(fs2.readFileSync(p, "utf-8"));
|
|
1233
|
+
} catch {
|
|
1234
|
+
return "";
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
var KIT_TEMPLATE_FALLBACK_DIRS, _moduleDir;
|
|
1238
|
+
var init_templateLoader = __esm({
|
|
1239
|
+
"src/services/templateLoader.ts"() {
|
|
1240
|
+
KIT_TEMPLATE_FALLBACK_DIRS = [
|
|
1241
|
+
// Packaged with the npm bundle (dist/templates) — resolves from node_modules.
|
|
1242
|
+
"templates",
|
|
1243
|
+
// Repo checkout layouts.
|
|
1244
|
+
"docs/refs/templates"
|
|
1245
|
+
];
|
|
1246
|
+
_moduleDir = (() => {
|
|
1247
|
+
try {
|
|
1248
|
+
if (typeof import.meta !== "undefined" && typeof import.meta.url === "string") {
|
|
1249
|
+
return path.dirname(fileURLToPath(import.meta.url));
|
|
1250
|
+
}
|
|
1251
|
+
} catch {
|
|
1252
|
+
}
|
|
1253
|
+
return typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
1254
|
+
})();
|
|
1255
|
+
}
|
|
1256
|
+
});
|
|
1130
1257
|
|
|
1131
1258
|
// src/parsers/lessonFlowParser.ts
|
|
1132
1259
|
var init_lessonFlowParser = __esm({
|
|
1133
1260
|
"src/parsers/lessonFlowParser.ts"() {
|
|
1261
|
+
init_templateLoader();
|
|
1134
1262
|
}
|
|
1135
1263
|
});
|
|
1136
1264
|
|
|
@@ -2745,468 +2873,8 @@ z.object({
|
|
|
2745
2873
|
phases: z.array(PhaseInputSchema).default([])
|
|
2746
2874
|
});
|
|
2747
2875
|
|
|
2748
|
-
// src/templates/lessonTemplate.ts
|
|
2749
|
-
var LESSON_PLAN_TEMPLATE = `
|
|
2750
|
-
---
|
|
2751
|
-
id: "{{ID}}"
|
|
2752
|
-
title: "{{TITLE}}"
|
|
2753
|
-
type: "LESSON_5E"
|
|
2754
|
-
created_by: "Curriculum OS Builder"
|
|
2755
|
-
phase: "{{PHASE}}"
|
|
2756
|
-
deliverable: "P3-T1"
|
|
2757
|
-
version: "{{VERSION}}"
|
|
2758
|
-
date: "{{DATE}}"
|
|
2759
|
-
prerequisite: []
|
|
2760
|
-
template_contract: "lesson-plan-v2"
|
|
2761
|
-
template_required_sections:
|
|
2762
|
-
- "A. Lesson Design Plan"
|
|
2763
|
-
- "Learning Objectives & Evidence"
|
|
2764
|
-
- "Activity Sequence"
|
|
2765
|
-
- "Resource Map"
|
|
2766
|
-
- "Assessment Map"
|
|
2767
|
-
- "Artifact Contract"
|
|
2768
|
-
- "B. Lesson Flow"
|
|
2769
|
-
---
|
|
2770
|
-
<!-- INJECT_BODY -->
|
|
2771
|
-
|
|
2772
|
-
# LESSON [{{LESSON_ID}}]: {{TITLE}} (5E Model)
|
|
2773
|
-
|
|
2774
|
-
## [REQUIRED] A. Lesson Design Plan
|
|
2775
|
-
|
|
2776
|
-
### 1. Learning Objectives & Evidence
|
|
2777
|
-
- **Estimated Duration:** {{DURATION}}
|
|
2778
|
-
- **Materials & Equipment:** {{MATERIALS_SUMMARY}}
|
|
2779
|
-
- **Keywords / Core Concepts:** {{KEYWORDS}}
|
|
2780
|
-
|
|
2781
|
-
| LO | Objective (Bloom's) | Student Evidence | Success Criteria |
|
|
2782
|
-
|---|---|---|---|
|
|
2783
|
-
{{LEARNING_OBJECTIVES_TABLE_ROWS}}
|
|
2784
|
-
|
|
2785
|
-
### 2. Activity Sequence
|
|
2786
|
-
> This is the canonical activity contract. Satellite artifacts must expand this sequence and must not invent a different one.
|
|
2787
|
-
|
|
2788
|
-
| Seq | 5E Phase | Activity Type | Actor | Purpose | Student Action | Teacher Move | Output/Evidence | LO | Time | Artifact Contract |
|
|
2789
|
-
|---|---|---|---|---|---|---|---|---|---|---|
|
|
2790
|
-
{{ACTIVITY_SEQUENCE_TABLE_ROWS}}
|
|
2791
|
-
|
|
2792
|
-
### 3. Resource Map
|
|
2793
|
-
| Resource | Used In Activity | Purpose | Owner Artifact |
|
|
2794
|
-
|---|---|---|---|
|
|
2795
|
-
{{RESOURCE_MAP_TABLE_ROWS}}
|
|
2796
|
-
|
|
2797
|
-
### 4. Assessment Map
|
|
2798
|
-
| Evidence | Assessed By | Criteria | Follow-up If Missing |
|
|
2799
|
-
|---|---|---|---|
|
|
2800
|
-
{{ASSESSMENT_MAP_TABLE_ROWS}}
|
|
2801
|
-
|
|
2802
|
-
### 5. Artifact Contract
|
|
2803
|
-
- **ACT must expand:** {{ACT_CONTRACT}}
|
|
2804
|
-
- **GUIDE must support:** {{GUIDE_CONTRACT}}
|
|
2805
|
-
- **SLIDE must visualize:** {{SLIDE_CONTRACT}}
|
|
2806
|
-
- **HANDOUT must provide:** {{HANDOUT_CONTRACT}}
|
|
2807
|
-
- **WKS must practice:** {{WKS_CONTRACT}}
|
|
2808
|
-
- **QUIZ must assess:** {{QUIZ_CONTRACT}}
|
|
2809
|
-
- **EXT must extend:** {{EXT_CONTRACT}}
|
|
2810
|
-
|
|
2811
|
-
---
|
|
2812
|
-
|
|
2813
|
-
## [REQUIRED] B. Lesson Flow
|
|
2814
|
-
|
|
2815
|
-
### 1. ENGAGE \u2014 {{ENGAGE_DURATION}} mins
|
|
2816
|
-
- **Hook Scenario:** {{HOOK_SCENARIO}}
|
|
2817
|
-
- **Open Question:** {{HOOK_OPEN_QUESTION}}
|
|
2818
|
-
- **Transition:** {{HOOK_TRANSITION}}
|
|
2819
|
-
|
|
2820
|
-
### 2. EXPLORE \u2014 {{EXPLORE_DURATION}} mins
|
|
2821
|
-
- **Activity Reference:** {{EXPLORE_ACTIVITY_REF}}
|
|
2822
|
-
- **Student Discovery:** {{EXPLORE_STUDENT_DISCOVERY}}
|
|
2823
|
-
|
|
2824
|
-
### 3. EXPLAIN \u2014 {{EXPLAIN_DURATION}} mins
|
|
2825
|
-
- **Definitions:**
|
|
2826
|
-
{{EXPLAIN_DEFINITIONS}}
|
|
2827
|
-
- **Visual Illustration (REQUIRED):**
|
|
2828
|
-
{{EXPLAIN_VISUAL_ILLUSTRATION}}
|
|
2829
|
-
|
|
2830
|
-
### 4. ELABORATE \u2014 {{ELABORATE_DURATION}} mins
|
|
2831
|
-
- **Tiered Scaffolding:**
|
|
2832
|
-
- \u{1F949} **Bronze:** {{DIFFERENTIATION_BRONZE}}
|
|
2833
|
-
- \u{1F948} **Silver:** {{DIFFERENTIATION_SILVER}}
|
|
2834
|
-
- \u{1F947} **Gold:** {{DIFFERENTIATION_GOLD}}
|
|
2835
|
-
|
|
2836
|
-
> **ACT Contract**: Detailed operational instructions must expand the Activity Sequence above and must not change the planned evidence target.
|
|
2837
|
-
|
|
2838
|
-
### 5. EVALUATE \u2014 {{EVALUATE_DURATION}} mins
|
|
2839
|
-
- **Exit Ticket:** {{EXIT_TICKET_CONTENT}}
|
|
2840
|
-
- **Closing:** {{CLOSING_REMARKS}}
|
|
2841
|
-
|
|
2842
|
-
> **QUIZ Contract**: Detailed assessment criteria and rubrics must assess the evidence and success criteria defined in the Lesson Design Plan.
|
|
2843
|
-
|
|
2844
|
-
---
|
|
2845
|
-
|
|
2846
|
-
## [OPTIONAL] Teacher Notes
|
|
2847
|
-
- **Common Pitfalls:**
|
|
2848
|
-
{{COMMON_PITFALLS}}
|
|
2849
|
-
- **Troubleshooting:**
|
|
2850
|
-
{{TROUBLESHOOTING_ROWS}}
|
|
2851
|
-
|
|
2852
|
-
---
|
|
2853
|
-
|
|
2854
|
-
## [REQUIRED] Artifact Linkage (Master Index)
|
|
2855
|
-
> List all satellite files used in this lesson.
|
|
2856
|
-
|
|
2857
|
-
| Artifact File | Role in the Classroom | When to Use |
|
|
2858
|
-
|---|---|---|
|
|
2859
|
-
| \`GUIDE_{{LESSON_ID}}.md\` | Detailed Teaching Script | Teacher preparation |
|
|
2860
|
-
| \`SLIDE_{{LESSON_ID}}.md\` | Presentation Content | Throughout the session |
|
|
2861
|
-
| \`HANDOUT_{{LESSON_ID}}.md\` | Theory Summary for Students | During EXPLAIN phase |
|
|
2862
|
-
| \`ACT_{{LESSON_ID}}.md\` | Detailed Learning Activity Operations | During EXPLORE / ELABORATE / checkpoint phases |
|
|
2863
|
-
| \`WKS_{{LESSON_ID}}.md\` | Individual Worksheet | Wrap-up or Homework |
|
|
2864
|
-
| \`QUIZ_{{LESSON_ID}}.md\` | Assessment Rubric | During EVALUATE phase |
|
|
2865
|
-
| \`EXT_{{LESSON_ID}}.md\` | Enrichment Materials | For "Gold" students |
|
|
2866
|
-
`.trim();
|
|
2867
|
-
|
|
2868
|
-
// src/templates/actTemplate.ts
|
|
2869
|
-
var ACT_TEMPLATE = `
|
|
2870
|
-
---
|
|
2871
|
-
id: "{{ID}}"
|
|
2872
|
-
title: "{{TITLE}}"
|
|
2873
|
-
type: "ACT"
|
|
2874
|
-
created_by: "Curriculum OS Builder"
|
|
2875
|
-
phase: "{{PHASE}}"
|
|
2876
|
-
deliverable: "P3-T2"
|
|
2877
|
-
version: "{{VERSION}}"
|
|
2878
|
-
date: "{{DATE}}"
|
|
2879
|
-
template_contract: "artifact-template-v1"
|
|
2880
|
-
template_required_sections:
|
|
2881
|
-
- "Computational Thinking Focus"
|
|
2882
|
-
- "Materials & Setup"
|
|
2883
|
-
- "Constraints & Safety"
|
|
2884
|
-
- "Active Learning Workflow"
|
|
2885
|
-
- "3-Tier Differentiation"
|
|
2886
|
-
- "Reflection"
|
|
2887
|
-
---
|
|
2888
|
-
<!-- INJECT_BODY -->
|
|
2889
|
-
|
|
2890
|
-
# INQUIRY-BASED ACTIVITY: {{TITLE}}
|
|
2891
|
-
_Milestone: {{MILESTONE_ID}} | Module: {{MODULE_NAME}} | Lesson: {{LESSON_ID}}_
|
|
2892
|
-
|
|
2893
|
-
## [REQUIRED] Computational Thinking Focus
|
|
2894
|
-
- **Problem Statement (Real-world Scenario):** {{PROBLEM_STATEMENT}}
|
|
2895
|
-
- **Decomposition:**
|
|
2896
|
-
{{DECOMPOSITION_STEPS}}
|
|
2897
|
-
- **Algorithm Design:** {{ALGORITHM_DESIGN}}
|
|
2898
|
-
|
|
2899
|
-
## [REQUIRED] Materials & Setup
|
|
2900
|
-
- **Reference Material:** Students should use the **HANDOUT** for this lesson as their primary technical reference (lifeline).
|
|
2901
|
-
- **Hardware/Software:**
|
|
2902
|
-
<!-- [HARDWARE_BOM] -->
|
|
2903
|
-
{{HARDWARE_ITEMS}}
|
|
2904
|
-
<!-- [/HARDWARE_BOM] -->
|
|
2905
|
-
- **Software:** {{SOFTWARE_ITEMS}}
|
|
2906
|
-
- **Consumables:** {{CONSUMABLES}}
|
|
2907
|
-
- **Other Resources:** {{OTHER_RESOURCES}}
|
|
2908
|
-
|
|
2909
|
-
## [REQUIRED] Constraints & Safety
|
|
2910
|
-
- \u26A0\uFE0F **Technical/Safety:** {{SAFETY_WARNING}}
|
|
2911
|
-
- \u{1F4A1} **Design Constraint:** {{DESIGN_CONSTRAINT}}
|
|
2912
|
-
|
|
2913
|
-
## [REQUIRED] Active Learning Workflow
|
|
2914
|
-
|
|
2915
|
-
### Phase 1: Planning & Design \u2014 {{PHASE1_DURATION}} mins
|
|
2916
|
-
- **Student Task:** Hand-draw (or draft in words) the algorithm flowchart or connection architecture before touching the computer/devices.
|
|
2917
|
-
- **Teacher Action:** Walk around to check the logic of each group. Ask inquiry questions:
|
|
2918
|
-
{{PHASE1_INQUIRY_QUESTIONS}}
|
|
2919
|
-
|
|
2920
|
-
### Phase 2: Implementation & Discovery \u2014 {{PHASE2_DURATION}} mins
|
|
2921
|
-
- **Student Task:** Apply the knowledge from the **HANDOUT** to realize the plan designed in Phase 1. Encourage self-inquiry and documentation lookup.
|
|
2922
|
-
- **Teacher Action:** Avoid "hand-holding." Only intervene if a group has been stuck for more than 5 minutes.
|
|
2923
|
-
{{PHASE2_GUIDANCE_BLOCK}}
|
|
2924
|
-
|
|
2925
|
-
### Phase 3: Debugging & Testing \u2014 {{PHASE3_DURATION}} mins
|
|
2926
|
-
- **Testing:** Students run their system.
|
|
2927
|
-
- **Error Analysis:** Ask students to record any error codes or unexpected behaviors and compare them with the Troubleshooting table in the Handout.
|
|
2928
|
-
{{PHASE3_TESTING_STEPS}}
|
|
2929
|
-
|
|
2930
|
-
## [REQUIRED] 3-Tier Differentiation
|
|
2931
|
-
> MUST design tasks in 3 tiers to support diverse learner groups. Bronze is the minimum requirement for all students.
|
|
2932
|
-
- \u{1F949} **Bronze (Foundational):** {{DIFFERENTIATION_BRONZE}}
|
|
2933
|
-
- \u{1F948} **Silver (Application):** {{DIFFERENTIATION_SILVER}}
|
|
2934
|
-
- \u{1F947} **Gold (Enrichment/Creative):** {{DIFFERENTIATION_GOLD}}
|
|
2935
|
-
|
|
2936
|
-
## [REQUIRED] Reflection
|
|
2937
|
-
- **Discussion Question:** {{REFLECTION_QUESTION}}
|
|
2938
|
-
`.trim();
|
|
2939
|
-
|
|
2940
|
-
// src/templates/codeLabTemplate.ts
|
|
2941
|
-
var CODE_LAB_TEMPLATE = `
|
|
2942
|
-
---
|
|
2943
|
-
id: "{{ID}}"
|
|
2944
|
-
title: "{{TITLE}}"
|
|
2945
|
-
type: "LAB"
|
|
2946
|
-
created_by: "Curriculum OS Builder"
|
|
2947
|
-
phase: "{{PHASE}}"
|
|
2948
|
-
deliverable: "P3-T2"
|
|
2949
|
-
version: "{{VERSION}}"
|
|
2950
|
-
date: "{{DATE}}"
|
|
2951
|
-
---
|
|
2952
|
-
<!-- INJECT_BODY -->
|
|
2953
|
-
|
|
2954
|
-
# \u{1F468}\u200D\u{1F4BB} CODE LAB: {{TITLE}}
|
|
2955
|
-
_Milestone: {{MILESTONE_ID}} | Tech Stack: {{TECH_STACK}}_
|
|
2956
|
-
|
|
2957
|
-
## \u{1F3AF} Overview
|
|
2958
|
-
This lab focuses on the practical implementation of core technical concepts, bridging theory into working, robust, and testable code.
|
|
2959
|
-
|
|
2960
|
-
## \u{1F6E0}\uFE0F Environment & Setup
|
|
2961
|
-
- **Language / Framework:** {{LANGUAGE_FRAMEWORK}}
|
|
2962
|
-
- **IDE / Editor:** {{IDE_EDITOR}}
|
|
2963
|
-
- **Required Libraries:** {{REQUIRED_LIBRARIES}}
|
|
2964
|
-
- **Hardware / Connection Setup:** {{HARDWARE_ENV_CONNECTION}}
|
|
2965
|
-
|
|
2966
|
-
## \u{1F4DD} Lab Tasks (3-Tier Differentiation)
|
|
2967
|
-
|
|
2968
|
-
### \u{1F949} Bronze (Foundational) \u2014 {{BRONZE_MINS}} mins
|
|
2969
|
-
**Objective:** {{BRONZE_OBJECTIVE}}
|
|
2970
|
-
- **Task:** {{BRONZE_TASK}}
|
|
2971
|
-
- **Requirement:** {{BRONZE_REQUIREMENT}}
|
|
2972
|
-
|
|
2973
|
-
### \u{1F948} Silver (Application) \u2014 {{SILVER_MINS}} mins
|
|
2974
|
-
**Objective:** {{SILVER_OBJECTIVE}}
|
|
2975
|
-
- **Task:** {{SILVER_TASK}}
|
|
2976
|
-
- **Requirement:** {{SILVER_REQUIREMENT}}
|
|
2977
|
-
|
|
2978
|
-
### \u{1F947} Gold (Enrichment/Creative) \u2014 {{GOLD_MINS}} mins
|
|
2979
|
-
**Objective:** {{GOLD_OBJECTIVE}}
|
|
2980
|
-
- **Task:** {{GOLD_TASK}}
|
|
2981
|
-
- **Requirement:** {{GOLD_REQUIREMENT}}
|
|
2982
|
-
|
|
2983
|
-
## \u{1F4BB} Technical Reference ([SME_MANDATE])
|
|
2984
|
-
<!-- [SME_MANDATE] -->
|
|
2985
|
-
> Any code provided in this section is verified for syntax accuracy and runtime execution.
|
|
2986
|
-
|
|
2987
|
-
### Starter Code Template
|
|
2988
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
2989
|
-
{{STARTER_CODE}}
|
|
2990
|
-
\`\`\`
|
|
2991
|
-
|
|
2992
|
-
### Solution Code
|
|
2993
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
2994
|
-
{{SOLUTION_CODE}}
|
|
2995
|
-
\`\`\`
|
|
2996
|
-
<!-- [/SME_MANDATE] -->
|
|
2997
|
-
|
|
2998
|
-
## \u{1F50D} Troubleshooting & Debugging Matrix
|
|
2999
|
-
| Issue | Potential Cause | Solution |
|
|
3000
|
-
| :--- | :--- | :--- |
|
|
3001
|
-
{{TROUBLESHOOTING_ROWS}}
|
|
3002
|
-
|
|
3003
|
-
## \u{1F3C1} Submission & Verification Checklist
|
|
3004
|
-
{{CHECKLIST_ITEMS}}
|
|
3005
|
-
`.trim();
|
|
3006
|
-
|
|
3007
|
-
// src/templates/quizTemplate.ts
|
|
3008
|
-
var QUIZ_TEMPLATE = `
|
|
3009
|
-
---
|
|
3010
|
-
id: "{{ID}}"
|
|
3011
|
-
title: "{{TITLE}}"
|
|
3012
|
-
type: "QUIZ"
|
|
3013
|
-
language: "{{LANGUAGE}}"
|
|
3014
|
-
total_questions: {{TOTAL_QUESTIONS}}
|
|
3015
|
-
passing_score_pct: {{PASSING_SCORE_PCT}}
|
|
3016
|
-
---
|
|
3017
|
-
|
|
3018
|
-
# \u{1F9E0} Diagnostic & Active Recall Quiz: {{TITLE}}
|
|
3019
|
-
|
|
3020
|
-
> \u23F1\uFE0F **Recommended Time:** ~10-15 mins
|
|
3021
|
-
> \u{1F3AF} **Passing Score:** {{PASSING_SCORE_PCT}}%
|
|
3022
|
-
> \u{1F4A1} **Purpose:** Test your conceptual understanding, catch hidden misconceptions, and evaluate architectural trade-offs.
|
|
3023
|
-
|
|
3024
|
-
---
|
|
3025
|
-
|
|
3026
|
-
{{QUESTIONS_SECTION}}
|
|
3027
|
-
|
|
3028
|
-
---
|
|
3029
|
-
|
|
3030
|
-
## \u{1F511} Comprehensive Answer Key & Deep Explanation (Expand after completing)
|
|
3031
|
-
<details>
|
|
3032
|
-
<summary><b>\u{1F449} Click to View Full Explanations & Common Pitfall Analysis</b></summary>
|
|
3033
|
-
|
|
3034
|
-
{{ANSWER_KEY_SECTION}}
|
|
3035
|
-
</details>
|
|
3036
|
-
`.trim();
|
|
3037
|
-
|
|
3038
|
-
// src/templates/selfLabTemplate.ts
|
|
3039
|
-
var SELF_LAB_TEMPLATE = `
|
|
3040
|
-
---
|
|
3041
|
-
id: "{{ID}}"
|
|
3042
|
-
title: "{{TITLE}}"
|
|
3043
|
-
type: "SELF_LAB"
|
|
3044
|
-
language: "{{LANGUAGE}}"
|
|
3045
|
-
difficulty: "{{DIFFICULTY}}"
|
|
3046
|
-
estimated_minutes: {{ESTIMATED_MINUTES}}
|
|
3047
|
-
tech_stack: {{TECH_STACK}}
|
|
3048
|
-
---
|
|
3049
|
-
|
|
3050
|
-
# \u{1F680} Self-Paced Hands-On Lab: {{TITLE}}
|
|
3051
|
-
|
|
3052
|
-
> \u23F1\uFE0F **Estimated Duration:** ~{{ESTIMATED_MINUTES}} mins
|
|
3053
|
-
> \u{1F3AF} **Difficulty Level:** {{DIFFICULTY_UPPER}}
|
|
3054
|
-
> \u{1F9F0} **Tech Stack:** {{TECH_STACK_STR}}
|
|
3055
|
-
> \u{1F4A1} **Self-Learner Notice:** You are in full control of this lab. Follow the progressive challenges below. If you get stuck at any point, use the **Progressive Hints System** to get unstuck without ruining the learning experience!
|
|
3056
|
-
|
|
3057
|
-
---
|
|
3058
|
-
|
|
3059
|
-
## \u{1F4CB} Mission Briefing & Environment Setup
|
|
3060
|
-
{{MISSION_BRIEFING}}
|
|
3061
|
-
|
|
3062
|
-
### \u{1F6EB} Preflight Checklist
|
|
3063
|
-
{{PREFLIGHT_CHECKLIST}}
|
|
3064
|
-
|
|
3065
|
-
---
|
|
3066
|
-
|
|
3067
|
-
## \u{1F3AF} Progressive Challenges (3-Tier Differentiation)
|
|
3068
|
-
|
|
3069
|
-
### \u{1F949} Challenge 1: Foundational Core (Bronze) \u2014 ~{{BRONZE_MINS}} mins
|
|
3070
|
-
**Objective:** {{BRONZE_OBJECTIVE}}
|
|
3071
|
-
|
|
3072
|
-
#### Tasks & Implementation Details:
|
|
3073
|
-
{{BRONZE_TASKS}}
|
|
3074
|
-
|
|
3075
|
-
#### \u{1F9EA} Self-Verification Command:
|
|
3076
|
-
\`\`\`bash
|
|
3077
|
-
{{BRONZE_VERIFY_COMMAND}}
|
|
3078
|
-
\`\`\`
|
|
3079
|
-
*Expected Terminal Output:*
|
|
3080
|
-
\`\`\`text
|
|
3081
|
-
{{BRONZE_EXPECTED_OUTPUT}}
|
|
3082
|
-
\`\`\`
|
|
3083
|
-
|
|
3084
|
-
#### \u{1F4A1} Progressive Hints (Expand only if stuck):
|
|
3085
|
-
<details>
|
|
3086
|
-
<summary><b>\u{1F4A1} Hint Level 1: Conceptual Clue (H\u01B0\u1EDBng t\u01B0 duy)</b></summary>
|
|
3087
|
-
|
|
3088
|
-
{{BRONZE_HINT_1}}
|
|
3089
|
-
</details>
|
|
3090
|
-
|
|
3091
|
-
<details>
|
|
3092
|
-
<summary><b>\u{1F50D} Hint Level 2: Structural Skeleton (Khung code m\u1EABu)</b></summary>
|
|
3093
|
-
|
|
3094
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
3095
|
-
{{BRONZE_HINT_2}}
|
|
3096
|
-
\`\`\`
|
|
3097
|
-
</details>
|
|
3098
|
-
|
|
3099
|
-
<details>
|
|
3100
|
-
<summary><b>\u{1F6A8} Hint Level 3: Full Solution & Explanation (L\u1EDDi gi\u1EA3i tr\u1ECDn v\u1EB9n)</b></summary>
|
|
3101
|
-
|
|
3102
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
3103
|
-
{{BRONZE_HINT_3_CODE}}
|
|
3104
|
-
\`\`\`
|
|
3105
|
-
|
|
3106
|
-
**Why this solution works:**
|
|
3107
|
-
{{BRONZE_HINT_3_EXPLANATION}}
|
|
3108
|
-
</details>
|
|
3109
|
-
|
|
3110
|
-
---
|
|
3111
|
-
|
|
3112
|
-
### \u{1F948} Challenge 2: Logic & Error Handling (Silver) \u2014 ~{{SILVER_MINS}} mins
|
|
3113
|
-
**Objective:** {{SILVER_OBJECTIVE}}
|
|
3114
|
-
|
|
3115
|
-
#### Tasks & Implementation Details:
|
|
3116
|
-
{{SILVER_TASKS}}
|
|
3117
|
-
|
|
3118
|
-
#### \u{1F9EA} Self-Verification Command:
|
|
3119
|
-
\`\`\`bash
|
|
3120
|
-
{{SILVER_VERIFY_COMMAND}}
|
|
3121
|
-
\`\`\`
|
|
3122
|
-
*Expected Terminal Output:*
|
|
3123
|
-
\`\`\`text
|
|
3124
|
-
{{SILVER_EXPECTED_OUTPUT}}
|
|
3125
|
-
\`\`\`
|
|
3126
|
-
|
|
3127
|
-
#### \u{1F4A1} Progressive Hints (Expand only if stuck):
|
|
3128
|
-
<details>
|
|
3129
|
-
<summary><b>\u{1F4A1} Hint Level 1: Conceptual Clue (H\u01B0\u1EDBng t\u01B0 duy)</b></summary>
|
|
3130
|
-
|
|
3131
|
-
{{SILVER_HINT_1}}
|
|
3132
|
-
</details>
|
|
3133
|
-
|
|
3134
|
-
<details>
|
|
3135
|
-
<summary><b>\u{1F50D} Hint Level 2: Structural Skeleton (Khung code m\u1EABu)</b></summary>
|
|
3136
|
-
|
|
3137
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
3138
|
-
{{SILVER_HINT_2}}
|
|
3139
|
-
\`\`\`
|
|
3140
|
-
</details>
|
|
3141
|
-
|
|
3142
|
-
<details>
|
|
3143
|
-
<summary><b>\u{1F6A8} Hint Level 3: Full Solution & Explanation (L\u1EDDi gi\u1EA3i tr\u1ECDn v\u1EB9n)</b></summary>
|
|
3144
|
-
|
|
3145
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
3146
|
-
{{SILVER_HINT_3_CODE}}
|
|
3147
|
-
\`\`\`
|
|
3148
|
-
|
|
3149
|
-
**Why this solution works:**
|
|
3150
|
-
{{SILVER_HINT_3_EXPLANATION}}
|
|
3151
|
-
</details>
|
|
3152
|
-
|
|
3153
|
-
---
|
|
3154
|
-
|
|
3155
|
-
### \u{1F947} Challenge 3: Edge Cases & Optimization (Gold) \u2014 ~{{GOLD_MINS}} mins
|
|
3156
|
-
**Objective:** {{GOLD_OBJECTIVE}}
|
|
3157
|
-
|
|
3158
|
-
#### Tasks & Implementation Details:
|
|
3159
|
-
{{GOLD_TASKS}}
|
|
3160
|
-
|
|
3161
|
-
#### \u{1F9EA} Self-Verification Command:
|
|
3162
|
-
\`\`\`bash
|
|
3163
|
-
{{GOLD_VERIFY_COMMAND}}
|
|
3164
|
-
\`\`\`
|
|
3165
|
-
*Expected Terminal Output:*
|
|
3166
|
-
\`\`\`text
|
|
3167
|
-
{{GOLD_EXPECTED_OUTPUT}}
|
|
3168
|
-
\`\`\`
|
|
3169
|
-
|
|
3170
|
-
#### \u{1F4A1} Progressive Hints (Expand only if stuck):
|
|
3171
|
-
<details>
|
|
3172
|
-
<summary><b>\u{1F4A1} Hint Level 1: Conceptual Clue (H\u01B0\u1EDBng t\u01B0 duy)</b></summary>
|
|
3173
|
-
|
|
3174
|
-
{{GOLD_HINT_1}}
|
|
3175
|
-
</details>
|
|
3176
|
-
|
|
3177
|
-
<details>
|
|
3178
|
-
<summary><b>\u{1F50D} Hint Level 2: Structural Skeleton (Khung code m\u1EABu)</b></summary>
|
|
3179
|
-
|
|
3180
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
3181
|
-
{{GOLD_HINT_2}}
|
|
3182
|
-
\`\`\`
|
|
3183
|
-
</details>
|
|
3184
|
-
|
|
3185
|
-
<details>
|
|
3186
|
-
<summary><b>\u{1F6A8} Hint Level 3: Full Solution & Explanation (L\u1EDDi gi\u1EA3i tr\u1ECDn v\u1EB9n)</b></summary>
|
|
3187
|
-
|
|
3188
|
-
\`\`\`{{CODE_LANGUAGE}}
|
|
3189
|
-
{{GOLD_HINT_3_CODE}}
|
|
3190
|
-
\`\`\`
|
|
3191
|
-
|
|
3192
|
-
**Why this solution works:**
|
|
3193
|
-
{{GOLD_HINT_3_EXPLANATION}}
|
|
3194
|
-
</details>
|
|
3195
|
-
|
|
3196
|
-
---
|
|
3197
|
-
|
|
3198
|
-
## \u{1F50D} Self-Learner Troubleshooting Matrix
|
|
3199
|
-
| Symptom / Error Message | Root Cause | Exact Fix |
|
|
3200
|
-
| :--- | :--- | :--- |
|
|
3201
|
-
{{TROUBLESHOOTING_ROWS}}
|
|
3202
|
-
|
|
3203
|
-
---
|
|
3204
|
-
|
|
3205
|
-
## \u{1F3C1} Final Lab Submission & Mastery Checklist
|
|
3206
|
-
{{FINAL_CHECKLIST}}
|
|
3207
|
-
`.trim();
|
|
3208
|
-
|
|
3209
2876
|
// src/ai/prompts/lessonMasterPrompt.ts
|
|
2877
|
+
init_templateLoader();
|
|
3210
2878
|
function buildLessonMasterPrompt(input) {
|
|
3211
2879
|
const { milestone, language, topic, targetAudience, contextContinuity, standardsContext } = input;
|
|
3212
2880
|
const learningObjectives = milestone.learning_objectives || [];
|
|
@@ -3258,7 +2926,7 @@ Build a deep, rigorous, and highly pedagogical Master Lesson Plan (LESSON) that
|
|
|
3258
2926
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3259
2927
|
You MUST generate structured data that will render directly into this exact Markdown template:
|
|
3260
2928
|
---
|
|
3261
|
-
${
|
|
2929
|
+
${loadAuthoringTemplate("LESSON_5E_template.md") ?? "[TEMPLATE FILE NOT FOUND: LESSON_5E_template.md]"}
|
|
3262
2930
|
---
|
|
3263
2931
|
|
|
3264
2932
|
# INPUT PARAMETERS
|
|
@@ -3308,6 +2976,7 @@ Return a single valid JSON object matching the LessonPlanSchema with these exact
|
|
|
3308
2976
|
}
|
|
3309
2977
|
|
|
3310
2978
|
// src/ai/prompts/activityPrompt.ts
|
|
2979
|
+
init_templateLoader();
|
|
3311
2980
|
function buildActivityPrompt(input) {
|
|
3312
2981
|
const { lesson, language, hardwareBOM, softwareTools } = input;
|
|
3313
2982
|
const loList = lesson.learningObjectives.map((lo) => `- [${lo.bloomLevel}] ${lo.code}: ${lo.name || ""} \u2014 ${lo.description}${lo.successCriteria ? ` (Evidence: ${lo.successCriteria})` : ""}`).join("\n");
|
|
@@ -3336,7 +3005,7 @@ Transform the exact pedagogical flow and activities from the Master Lesson Plan
|
|
|
3336
3005
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3337
3006
|
You MUST generate data aligned with this Markdown template:
|
|
3338
3007
|
---
|
|
3339
|
-
${
|
|
3008
|
+
${loadAuthoringTemplate("ACT_template.md") ?? "[TEMPLATE FILE NOT FOUND: ACT_template.md]"}
|
|
3340
3009
|
---
|
|
3341
3010
|
|
|
3342
3011
|
# CANONICAL MASTER LESSON CONTEXT (SOURCE OF TRUTH)
|
|
@@ -3407,6 +3076,7 @@ Return a single JSON object matching ActivityLabSchema with these exact keys:
|
|
|
3407
3076
|
}
|
|
3408
3077
|
|
|
3409
3078
|
// src/ai/prompts/codeLabPrompt.ts
|
|
3079
|
+
init_templateLoader();
|
|
3410
3080
|
function buildCodeLabPrompt(input) {
|
|
3411
3081
|
const { lesson, activity, language, targetTechStack } = input;
|
|
3412
3082
|
const techStackList = targetTechStack && targetTechStack.length > 0 ? targetTechStack : ["General Programming & Engineering"];
|
|
@@ -3431,7 +3101,7 @@ Generate complete, verified source code that satisfies the lesson objectives and
|
|
|
3431
3101
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3432
3102
|
You MUST generate data aligned with this Markdown template:
|
|
3433
3103
|
---
|
|
3434
|
-
${
|
|
3104
|
+
${loadAuthoringTemplate("LAB_TEMPLATE.md") ?? "[TEMPLATE FILE NOT FOUND: LAB_TEMPLATE.md]"}
|
|
3435
3105
|
---
|
|
3436
3106
|
|
|
3437
3107
|
# CANONICAL LESSON CONTEXT (SOURCE OF TRUTH)
|
|
@@ -3813,6 +3483,7 @@ Please return a single JSON object matching these exact keys:
|
|
|
3813
3483
|
}
|
|
3814
3484
|
|
|
3815
3485
|
// src/ai/prompts/selfLabPrompt.ts
|
|
3486
|
+
init_templateLoader();
|
|
3816
3487
|
function buildSelfLabPrompt(input) {
|
|
3817
3488
|
const { milestone, projectGraph, language, targetTechStack, contextContinuity } = input;
|
|
3818
3489
|
const techStackList = targetTechStack && targetTechStack.length > 0 ? targetTechStack : milestone.tech_keywords && milestone.tech_keywords.length > 0 ? milestone.tech_keywords : ["General Engineering"];
|
|
@@ -3843,7 +3514,7 @@ Build a complete, engaging Self-Paced Hands-On Lab (SELF_LAB) for autonomous lea
|
|
|
3843
3514
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3844
3515
|
You MUST generate data aligned with this Markdown template:
|
|
3845
3516
|
---
|
|
3846
|
-
${
|
|
3517
|
+
${loadAuthoringTemplate("SELF_LAB_template.md") ?? "[TEMPLATE FILE NOT FOUND: SELF_LAB_template.md]"}
|
|
3847
3518
|
---
|
|
3848
3519
|
|
|
3849
3520
|
# INPUT PARAMETERS
|
|
@@ -3921,6 +3592,7 @@ Return a single valid JSON object matching SelfLabSchema with these exact keys:
|
|
|
3921
3592
|
}
|
|
3922
3593
|
|
|
3923
3594
|
// src/ai/prompts/diagnosticQuizPrompt.ts
|
|
3595
|
+
init_templateLoader();
|
|
3924
3596
|
function buildDiagnosticQuizPrompt(input) {
|
|
3925
3597
|
const { milestone, language, questionCount = 4, passingScorePct = 80 } = input;
|
|
3926
3598
|
const learningObjectives = milestone.learning_objectives || [];
|
|
@@ -3980,7 +3652,7 @@ Use this mapping to determine which Bloom level each question truly targets. Mat
|
|
|
3980
3652
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3981
3653
|
You MUST generate data aligned with this Markdown template:
|
|
3982
3654
|
---
|
|
3983
|
-
${
|
|
3655
|
+
${loadAuthoringTemplate("QUIZ_v4.6_template.md") ?? "[TEMPLATE FILE NOT FOUND: QUIZ_v4.6_template.md]"}
|
|
3984
3656
|
---
|
|
3985
3657
|
|
|
3986
3658
|
# INPUT PARAMETERS
|
|
@@ -4470,7 +4142,7 @@ ${cc.technicalDepth}`;
|
|
|
4470
4142
|
const dataRows = cc.comparisonTable.rows.map((r) => `| ${r.join(" | ")} |`).join("\n");
|
|
4471
4143
|
str += `
|
|
4472
4144
|
|
|
4473
|
-
|
|
4145
|
+
**Comparison & Trade-off Analysis**
|
|
4474
4146
|
${headerRow}
|
|
4475
4147
|
${dividerRow}
|
|
4476
4148
|
${dataRows}`;
|
|
@@ -4514,7 +4186,8 @@ ${learningObjectivesStr}
|
|
|
4514
4186
|
|
|
4515
4187
|
---
|
|
4516
4188
|
|
|
4517
|
-
## 1. ENGAGE (Hook & High-Stakes Scenario)
|
|
4189
|
+
## 1. ENGAGE (Hook & High-Stakes Scenario)
|
|
4190
|
+
> **Duration:** 10-15 mins
|
|
4518
4191
|
|
|
4519
4192
|
### Real-World Context: "${lesson.hookTitle || "The Incident"}"
|
|
4520
4193
|
${lesson.hookScenario}
|
|
@@ -4523,13 +4196,15 @@ ${lesson.hookQuestions && lesson.hookQuestions.length > 0 ? lesson.hookQuestions
|
|
|
4523
4196
|
|
|
4524
4197
|
---
|
|
4525
4198
|
|
|
4526
|
-
## 2. EXPLORE & EXPLAIN (Core Technical Concepts & Principles)
|
|
4199
|
+
## 2. EXPLORE & EXPLAIN (Core Technical Concepts & Principles)
|
|
4200
|
+
> **Duration:** 30-40 mins
|
|
4527
4201
|
|
|
4528
4202
|
${coreConceptsStr}
|
|
4529
4203
|
|
|
4530
4204
|
---
|
|
4531
4205
|
|
|
4532
|
-
## 3. GUIDED PRACTICE (Visual Architecture & Annotated Code)
|
|
4206
|
+
## 3. GUIDED PRACTICE (Visual Architecture & Annotated Code)
|
|
4207
|
+
> **Duration:** 20-25 mins
|
|
4533
4208
|
|
|
4534
4209
|
### System Architecture & Data Flow (Mermaid Diagram)
|
|
4535
4210
|
${mermaidBlock}
|
|
@@ -4543,7 +4218,8 @@ ${guidedPractice.codeSnippet}
|
|
|
4543
4218
|
|
|
4544
4219
|
---
|
|
4545
4220
|
|
|
4546
|
-
## 4. ELABORATE & INDEPENDENT PRACTICE (Technical Challenge & Scaffolding)
|
|
4221
|
+
## 4. ELABORATE & INDEPENDENT PRACTICE (Technical Challenge & Scaffolding)
|
|
4222
|
+
> **Duration:** 15-20 mins
|
|
4547
4223
|
|
|
4548
4224
|
### Engineering Challenge: "${lesson.independentPractice?.title || "System Optimization Challenge"}"
|
|
4549
4225
|
${lesson.independentPractice?.description || "Implement the core logic and test against simulated edge cases."}
|
|
@@ -4554,7 +4230,8 @@ ${lesson.independentPractice?.description || "Implement the core logic and test
|
|
|
4554
4230
|
|
|
4555
4231
|
---
|
|
4556
4232
|
|
|
4557
|
-
## 5. EVALUATE (Summary, Assessment & Metacognition)
|
|
4233
|
+
## 5. EVALUATE (Summary, Assessment & Metacognition)
|
|
4234
|
+
> **Duration:** 5-10 mins
|
|
4558
4235
|
|
|
4559
4236
|
### Exit Ticket (Bloom: Apply / Analyze)
|
|
4560
4237
|
> **Scenario Question:** ${lesson.exitTicket.questionStem}
|
|
@@ -4647,12 +4324,16 @@ ${hardwareItems}
|
|
|
4647
4324
|
|
|
4648
4325
|
## [REQUIRED] Active Learning Workflow
|
|
4649
4326
|
|
|
4650
|
-
### Phase 1: Planning & Design
|
|
4327
|
+
### Phase 1: Planning & Design
|
|
4328
|
+
> **Duration:** ${phase1.durationMinutes} mins
|
|
4329
|
+
|
|
4651
4330
|
- **Student Task:** ${phase1.studentTask}
|
|
4652
4331
|
- **Teacher Action:** ${phase1.teacherAction}
|
|
4653
4332
|
${phase1.inquiryQuestions.map((q) => ` - *Inquiry Question:* ${q}`).join("\n")}
|
|
4654
4333
|
|
|
4655
|
-
### Phase 2: Implementation & Discovery
|
|
4334
|
+
### Phase 2: Implementation & Discovery
|
|
4335
|
+
> **Duration:** ${phase2.durationMinutes} mins
|
|
4336
|
+
|
|
4656
4337
|
- **Student Task:** ${phase2.studentTask}
|
|
4657
4338
|
- **Teacher Action:** ${phase2.teacherAction}
|
|
4658
4339
|
|
|
@@ -4660,7 +4341,9 @@ ${phase2.codeOrCommands.map((c) => `\`\`\`text
|
|
|
4660
4341
|
${c}
|
|
4661
4342
|
\`\`\``).join("\n\n")}
|
|
4662
4343
|
|
|
4663
|
-
### Phase 3: Debugging & Testing
|
|
4344
|
+
### Phase 3: Debugging & Testing
|
|
4345
|
+
> **Duration:** ${phase3.durationMinutes} mins
|
|
4346
|
+
|
|
4664
4347
|
- **Testing:** ${phase3.testingSteps}
|
|
4665
4348
|
- **Error Analysis:** ${phase3.errorAnalysis}
|
|
4666
4349
|
|
|
@@ -4715,22 +4398,28 @@ This lab focuses on the practical implementation of core technical concepts, bri
|
|
|
4715
4398
|
|
|
4716
4399
|
## \u{1F4DD} Lab Tasks (3-Tier Differentiation)
|
|
4717
4400
|
|
|
4718
|
-
### \u{1F949} Bronze (Foundational)
|
|
4401
|
+
### \u{1F949} Bronze (Foundational)
|
|
4402
|
+
> **Duration:** ${tasks.bronze.mins} mins
|
|
4403
|
+
|
|
4719
4404
|
**Objective:** ${tasks.bronze.objective}
|
|
4720
4405
|
- **Task:** ${tasks.bronze.task}
|
|
4721
4406
|
- **Requirement:** ${tasks.bronze.requirement}
|
|
4722
4407
|
|
|
4723
|
-
### \u{1F948} Silver (Application)
|
|
4408
|
+
### \u{1F948} Silver (Application)
|
|
4409
|
+
> **Duration:** ${tasks.silver.mins} mins
|
|
4410
|
+
|
|
4724
4411
|
**Objective:** ${tasks.silver.objective}
|
|
4725
4412
|
- **Task:** ${tasks.silver.task}
|
|
4726
4413
|
- **Requirement:** ${tasks.silver.requirement}
|
|
4727
4414
|
|
|
4728
|
-
### \u{1F947} Gold (Enrichment/Creative)
|
|
4415
|
+
### \u{1F947} Gold (Enrichment/Creative)
|
|
4416
|
+
> **Duration:** ${tasks.gold.mins} mins
|
|
4417
|
+
|
|
4729
4418
|
**Objective:** ${tasks.gold.objective}
|
|
4730
4419
|
- **Task:** ${tasks.gold.task}
|
|
4731
4420
|
- **Requirement:** ${tasks.gold.requirement}
|
|
4732
4421
|
|
|
4733
|
-
## \u{1F4BB} Technical Reference
|
|
4422
|
+
## \u{1F4BB} Technical Reference
|
|
4734
4423
|
<!-- [SME_MANDATE] -->
|
|
4735
4424
|
> Any code provided in this section is verified for syntax accuracy and runtime execution.
|
|
4736
4425
|
|
|
@@ -4805,7 +4494,9 @@ ${proTipsStr}
|
|
|
4805
4494
|
function serializeSelfLabToMarkdown(lab) {
|
|
4806
4495
|
const renderChallenge = (c, label) => {
|
|
4807
4496
|
const tasksList = c.tasks.map((t) => `- ${t}`).join("\n");
|
|
4808
|
-
return `### ${label}: ${c.title}
|
|
4497
|
+
return `### ${label}: ${c.title}
|
|
4498
|
+
> **Duration:** ~${c.estimatedMinutes} mins
|
|
4499
|
+
|
|
4809
4500
|
**Objective:** ${c.objective}
|
|
4810
4501
|
|
|
4811
4502
|
#### Tasks & Implementation Details:
|
|
@@ -4963,7 +4654,7 @@ var LocalWorkspaceManager = class {
|
|
|
4963
4654
|
}
|
|
4964
4655
|
async initJobWorkspace(jobId, initialInfo) {
|
|
4965
4656
|
const jobDir = this.getJobDirectory(jobId);
|
|
4966
|
-
await
|
|
4657
|
+
await fs3.mkdir(jobDir, { recursive: true });
|
|
4967
4658
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4968
4659
|
const manifest = {
|
|
4969
4660
|
jobId,
|
|
@@ -4983,10 +4674,10 @@ var LocalWorkspaceManager = class {
|
|
|
4983
4674
|
async saveArtifact(jobId, milestoneSlug, filename, content, artifactType) {
|
|
4984
4675
|
const jobDir = this.getJobDirectory(jobId);
|
|
4985
4676
|
const targetDir = path.join(jobDir, milestoneSlug);
|
|
4986
|
-
await
|
|
4677
|
+
await fs3.mkdir(targetDir, { recursive: true });
|
|
4987
4678
|
const filePath = path.join(targetDir, filename);
|
|
4988
|
-
await
|
|
4989
|
-
const stat = await
|
|
4679
|
+
await fs3.writeFile(filePath, content, "utf-8");
|
|
4680
|
+
const stat = await fs3.stat(filePath);
|
|
4990
4681
|
const manifest = await this.getManifest(jobId);
|
|
4991
4682
|
if (manifest) {
|
|
4992
4683
|
manifest.artifacts.push({
|
|
@@ -5004,7 +4695,7 @@ var LocalWorkspaceManager = class {
|
|
|
5004
4695
|
async getManifest(jobId) {
|
|
5005
4696
|
const manifestPath = path.join(this.getJobDirectory(jobId), "manifest.json");
|
|
5006
4697
|
try {
|
|
5007
|
-
const data = await
|
|
4698
|
+
const data = await fs3.readFile(manifestPath, "utf-8");
|
|
5008
4699
|
return JSON.parse(data);
|
|
5009
4700
|
} catch {
|
|
5010
4701
|
return null;
|
|
@@ -5013,7 +4704,7 @@ var LocalWorkspaceManager = class {
|
|
|
5013
4704
|
async saveManifest(jobId, manifest) {
|
|
5014
4705
|
const manifestPath = path.join(this.getJobDirectory(jobId), "manifest.json");
|
|
5015
4706
|
manifest.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5016
|
-
await
|
|
4707
|
+
await fs3.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
5017
4708
|
}
|
|
5018
4709
|
async markMilestoneCompleted(jobId) {
|
|
5019
4710
|
const manifest = await this.getManifest(jobId);
|
|
@@ -5050,13 +4741,13 @@ async function publishToGitHub(options) {
|
|
|
5050
4741
|
try {
|
|
5051
4742
|
const filesToUpload = [];
|
|
5052
4743
|
async function scanDir(currentDir) {
|
|
5053
|
-
const entries = await
|
|
4744
|
+
const entries = await fs3.readdir(currentDir, { withFileTypes: true });
|
|
5054
4745
|
for (const entry of entries) {
|
|
5055
4746
|
const fullPath = path.join(currentDir, entry.name);
|
|
5056
4747
|
if (entry.isDirectory()) {
|
|
5057
4748
|
await scanDir(fullPath);
|
|
5058
4749
|
} else if (entry.isFile() && !entry.name.startsWith(".")) {
|
|
5059
|
-
const content = await
|
|
4750
|
+
const content = await fs3.readFile(fullPath, "utf-8");
|
|
5060
4751
|
const relPath = path.relative(options.localJobDir, fullPath);
|
|
5061
4752
|
filesToUpload.push({ path: relPath, content });
|
|
5062
4753
|
}
|
|
@@ -18915,6 +18606,7 @@ var LLMJudgeEngine = class {
|
|
|
18915
18606
|
init_errors();
|
|
18916
18607
|
|
|
18917
18608
|
// src/services/languageDirective.ts
|
|
18609
|
+
init_templateLoader();
|
|
18918
18610
|
function resolveTargetLanguageCode(language) {
|
|
18919
18611
|
const raw = String(language || "vi").trim().toLowerCase();
|
|
18920
18612
|
if (raw.startsWith("vi")) return "vi";
|
|
@@ -18955,137 +18647,58 @@ function matchesArtifactType(candidate, target) {
|
|
|
18955
18647
|
if ((c === "EXT" || c === "EXTENSION") && (t === "EXT" || t === "EXTENSION")) return true;
|
|
18956
18648
|
return false;
|
|
18957
18649
|
}
|
|
18958
|
-
var
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
"Examples & Context Rules": "Quy t\u1EAFc V\xED d\u1EE5 & Ng\u1EEF c\u1EA3nh",
|
|
18981
|
-
"Lesson Content Standards": "Ti\xEAu chu\u1EA9n N\u1ED9i dung B\xE0i h\u1ECDc"
|
|
18982
|
-
},
|
|
18983
|
-
SECTION_LANGUAGE_CONTRACT: {
|
|
18984
|
-
"Metadata & Scope": "Th\xF4ng tin & Ph\u1EA1m vi H\u1EE3p \u0111\u1ED3ng",
|
|
18985
|
-
"Section Translation Matrix": "Ma tr\u1EADn Ti\xEAu \u0111\u1EC1 \u0110a ng\xF4n ng\u1EEF",
|
|
18986
|
-
"Validation Rules": "Quy t\u1EAFc X\xE1c th\u1EF1c & Kh\xF3a Chu\u1EA9n"
|
|
18987
|
-
},
|
|
18988
|
-
KNOWLEDGE_EXPOSITION: {
|
|
18989
|
-
"Session Scope": "Ph\u1EA1m vi Bu\u1ED5i h\u1ECDc",
|
|
18990
|
-
"Key Terms": "Thu\u1EADt ng\u1EEF Then ch\u1ED1t",
|
|
18991
|
-
"Concept Narratives": "Di\u1EC5n gi\u1EA3i Kh\xE1i ni\u1EC7m",
|
|
18992
|
-
"Worked Micro-Examples": "V\xED d\u1EE5 M\u1EABu Chi ti\u1EBFt",
|
|
18993
|
-
"Common Mistakes": "L\u1ED7i Th\u01B0\u1EDDng g\u1EB7p & Kh\u1EAFc ph\u1EE5c",
|
|
18994
|
-
"Self-Check Questions": "C\xE2u h\u1ECFi T\u1EF1 ki\u1EC3m tra"
|
|
18995
|
-
},
|
|
18996
|
-
LESSON: {
|
|
18997
|
-
"A. Lesson Design Plan": "A. K\u1EBF ho\u1EA1ch Thi\u1EBFt k\u1EBF B\xE0i h\u1ECDc",
|
|
18998
|
-
"Learning Objectives & Evidence": "M\u1EE5c ti\xEAu H\u1ECDc t\u1EADp & B\u1EB1ng ch\u1EE9ng N\u0103ng l\u1EF1c",
|
|
18999
|
-
"Activity Sequence": "Chu\u1ED7i Ho\u1EA1t \u0111\u1ED9ng D\u1EA1y & H\u1ECDc",
|
|
19000
|
-
"Resource Map": "B\u1EA3n \u0111\u1ED3 T\xE0i nguy\xEAn & H\u1ECDc li\u1EC7u",
|
|
19001
|
-
"Assessment Map": "B\u1EA3n \u0111\u1ED3 \u0110\xE1nh gi\xE1 N\u0103ng l\u1EF1c",
|
|
19002
|
-
"Artifact Contract": "H\u1EE3p \u0111\u1ED3ng S\u1EA3n ph\u1EA9m \u0110\u1EA7u ra",
|
|
19003
|
-
"B. Lesson Flow": "B. Ti\u1EBFn tr\xECnh Gi\u1EA3ng d\u1EA1y Chi ti\u1EBFt"
|
|
19004
|
-
},
|
|
19005
|
-
ACT: {
|
|
19006
|
-
"Computational Thinking Focus": "Tr\u1ECDng t\xE2m T\u01B0 duy M\xE1y t\xEDnh",
|
|
19007
|
-
"Materials & Setup": "V\u1EADt li\u1EC7u & Chu\u1EA9n b\u1ECB Thi\u1EBFt b\u1ECB",
|
|
19008
|
-
"Constraints & Safety": "R\xE0ng bu\u1ED9c & An to\xE0n Ph\xF2ng th\u1EF1c h\xE0nh",
|
|
19009
|
-
"Active Learning Workflow": "Quy tr\xECnh Ho\u1EA1t \u0111\u1ED9ng Tr\u1EA3i nghi\u1EC7m",
|
|
19010
|
-
"3-Tier Differentiation": "Ph\xE2n h\xF3a H\u1ECDc t\u1EADp 3 T\u1EA7ng",
|
|
19011
|
-
"Reflection": "T\u1ED5ng k\u1EBFt & \u0110\xFAc k\u1EBFt Tr\u1EA3i nghi\u1EC7m"
|
|
19012
|
-
},
|
|
19013
|
-
CODE: {
|
|
19014
|
-
"Technical Overview & Architecture Blueprint": "T\u1ED5ng quan K\u1EF9 thu\u1EADt & B\u1EA3n thi\u1EBFt k\u1EBF Ki\u1EBFn tr\xFAc",
|
|
19015
|
-
"Hardware Pinout & Wiring Configuration Matrix": "S\u01A1 \u0111\u1ED3 Ch\xE2n & Ma tr\u1EADn N\u1ED1i d\xE2y Ph\u1EA7n c\u1EE9ng",
|
|
19016
|
-
"Starter Code Sandbox": "M\xE3 ngu\u1ED3n Kh\u1EDFi \u0111\u1EA7u (Starter Code)",
|
|
19017
|
-
"Verified Reference Solution Code": "M\xE3 ngu\u1ED3n L\u1EDDi gi\u1EA3i Chu\u1EA9n (Reference Solution)",
|
|
19018
|
-
"Automated Test / Verification Script": "K\u1ECBch b\u1EA3n Ki\u1EC3m th\u1EED T\u1EF1 \u0111\u1ED9ng",
|
|
19019
|
-
"Common Syntax & Runtime Pitfalls Matrix": "Ma tr\u1EADn L\u1ED7i C\xFA ph\xE1p & Th\u1EDDi gian ch\u1EA1y Th\u01B0\u1EDDng g\u1EB7p"
|
|
19020
|
-
},
|
|
19021
|
-
CODE_LAB: {
|
|
19022
|
-
"Technical Overview & Architecture Blueprint": "T\u1ED5ng quan K\u1EF9 thu\u1EADt & B\u1EA3n thi\u1EBFt k\u1EBF Ki\u1EBFn tr\xFAc",
|
|
19023
|
-
"Hardware Pinout & Wiring Configuration Matrix": "S\u01A1 \u0111\u1ED3 Ch\xE2n & Ma tr\u1EADn N\u1ED1i d\xE2y Ph\u1EA7n c\u1EE9ng",
|
|
19024
|
-
"Starter Code Sandbox": "M\xE3 ngu\u1ED3n Kh\u1EDFi \u0111\u1EA7u (Starter Code)",
|
|
19025
|
-
"Verified Reference Solution Code": "M\xE3 ngu\u1ED3n L\u1EDDi gi\u1EA3i Chu\u1EA9n (Reference Solution)",
|
|
19026
|
-
"Automated Test / Verification Script": "K\u1ECBch b\u1EA3n Ki\u1EC3m th\u1EED T\u1EF1 \u0111\u1ED9ng",
|
|
19027
|
-
"Common Syntax & Runtime Pitfalls Matrix": "Ma tr\u1EADn L\u1ED7i C\xFA ph\xE1p & Th\u1EDDi gian ch\u1EA1y Th\u01B0\u1EDDng g\u1EB7p"
|
|
19028
|
-
},
|
|
19029
|
-
QUIZ: {
|
|
19030
|
-
"Assessment Objectives": "M\u1EE5c ti\xEAu \u0110\xE1nh gi\xE1",
|
|
19031
|
-
"Multiple-Choice Question Bank": "Ng\xE2n h\xE0ng C\xE2u h\u1ECFi Tr\u1EAFc nghi\u1EC7m",
|
|
19032
|
-
"Code Analysis / Debugging Question": "C\xE2u h\u1ECFi Ph\xE2n t\xEDch M\xE3 ngu\u1ED3n & S\u1EEDa l\u1ED7i",
|
|
19033
|
-
"Competency Rubric": "Thang \u0111o \u0110\xE1nh gi\xE1 N\u0103ng l\u1EF1c (Rubric)"
|
|
19034
|
-
},
|
|
19035
|
-
GUIDE: {
|
|
19036
|
-
"Objectives & Preparation": "M\u1EE5c ti\xEAu & Chu\u1EA9n b\u1ECB Gi\u1EA3ng d\u1EA1y",
|
|
19037
|
-
"Preparation Checklist & Workstation Setup": "Danh m\u1EE5c Ki\u1EC3m tra Chu\u1EA9n b\u1ECB & Tr\u1EA1m Th\u1EF1c h\xE0nh",
|
|
19038
|
-
"Facilitation Script & Timeline": "K\u1ECBch b\u1EA3n \u0110i\u1EC1u ph\u1ED1i & Khung Th\u1EDDi gian",
|
|
19039
|
-
"Common Misconceptions & Diagnostic Remediation Matrix": "Quan ni\u1EC7m Sai l\u1EA7m Th\u01B0\u1EDDng g\u1EB7p & Ma tr\u1EADn Kh\u1EAFc ph\u1EE5c",
|
|
19040
|
-
"Differentiated Support Strategies": "Chi\u1EBFn l\u01B0\u1EE3c H\u1ED7 tr\u1EE3 Ph\xE2n h\xF3a"
|
|
19041
|
-
},
|
|
19042
|
-
HANDOUT: {
|
|
19043
|
-
"Core Concepts": "Kh\xE1i ni\u1EC7m C\u1ED1t l\xF5i",
|
|
19044
|
-
"Core Syntax & Mechanism Cheat Sheet": "B\u1EA3ng Tra c\u1EE9u C\xFA ph\xE1p & C\u01A1 ch\u1EBF Tr\u1ECDng t\xE2m",
|
|
19045
|
-
"Visual Mental Model / Architecture Diagram": "M\xF4 h\xECnh T\u01B0 duy Tr\u1EF1c quan / S\u01A1 \u0111\u1ED3 Ki\u1EBFn tr\xFAc",
|
|
19046
|
-
"Step-by-Step Practical Quick-Start Guide": "H\u01B0\u1EDBng d\u1EABn Th\u1EF1c h\xE0nh T\u1EEBng b\u01B0\u1EDBc",
|
|
19047
|
-
"Self-Check Diagnostic Checklist": "B\u1EA3ng Ki\u1EC3m tra T\u1EF1 ch\u1EA9n \u0111o\xE1n"
|
|
19048
|
-
},
|
|
19049
|
-
WKS: {
|
|
19050
|
-
"Part 1: Knowledge Check": "Ph\u1EA7n 1: Ki\u1EC3m tra Ki\u1EBFn th\u1EE9c",
|
|
19051
|
-
"Part 2: Concept Tracing & Diagram Fill-in": "Ph\u1EA7n 2: L\u1EA7n v\u1EBFt Kh\xE1i ni\u1EC7m & \u0110i\u1EC1n S\u01A1 \u0111\u1ED3",
|
|
19052
|
-
"Part 3: Code Analysis & Bug Hunting Challenge": "Ph\u1EA7n 3: Ph\xE2n t\xEDch M\xE3 & Th\u1EED th\xE1ch S\u0103n l\u1ED7i",
|
|
19053
|
-
"Part 4: Synthesis & Problem-Solving Application": "Ph\u1EA7n 4: T\u1ED5ng h\u1EE3p & \u1EE8ng d\u1EE5ng Gi\u1EA3i quy\u1EBFt V\u1EA5n \u0111\u1EC1",
|
|
19054
|
-
"Part 5: Self-Reflection & Learning Log": "Ph\u1EA7n 5: T\u1EF1 suy ng\u1EABm & Nh\u1EADt k\xFD H\u1ECDc t\u1EADp"
|
|
19055
|
-
},
|
|
19056
|
-
EXT: {
|
|
19057
|
-
"For: Advanced Students / Extra Time": "D\xE0nh cho: H\u1ECDc sinh N\xE2ng cao / Ho\xE0n th\xE0nh S\u1EDBm",
|
|
19058
|
-
"Challenge 1: Mission Briefing & Real-World High-Stakes Scenario": "Th\u1EED th\xE1ch 1: B\u1ED1i c\u1EA3nh Nhi\u1EC7m v\u1EE5 Th\u1EF1c t\u1EBF & K\u1ECBch b\u1EA3n \u1EE8ng d\u1EE5ng",
|
|
19059
|
-
"Challenge 2: Advanced Architectural Constraints & Edge Cases": "Th\u1EED th\xE1ch 2: R\xE0ng bu\u1ED9c Ki\u1EBFn tr\xFAc N\xE2ng cao & Tr\u01B0\u1EDDng h\u1EE3p Bi\xEAn",
|
|
19060
|
-
"Challenge 3: Extension Milestones": "Th\u1EED th\xE1ch 3: C\xE1c M\u1ED1c Nhi\u1EC7m v\u1EE5 N\xE2ng cao",
|
|
19061
|
-
"Metacognitive Deep Dive & Engineering Trade-offs": "Suy ng\u1EABm Si\xEAu nh\u1EADn th\u1EE9c & \u0110\xE1nh \u0111\u1ED5i K\u1EF9 thu\u1EADt"
|
|
19062
|
-
},
|
|
19063
|
-
SLIDE: {
|
|
19064
|
-
"Title & Agenda": "Ti\xEAu \u0111\u1EC1 & M\u1EE5c l\u1EE5c",
|
|
19065
|
-
"Core Concepts": "Kh\xE1i ni\u1EC7m C\u1ED1t l\xF5i",
|
|
19066
|
-
"Guided Demonstration": "H\u01B0\u1EDBng d\u1EABn Th\u1EF1c h\xE0nh & Th\u1ECB ph\u1EA1m",
|
|
19067
|
-
"Hands-on Mission": "Nhi\u1EC7m v\u1EE5 Th\u1EF1c h\xE0nh Tr\u1EA3i nghi\u1EC7m",
|
|
19068
|
-
"Summary & Next Steps": "T\u1ED5ng k\u1EBFt & \u0110\u1ECBnh h\u01B0\u1EDBng Ti\u1EBFp theo"
|
|
19069
|
-
}
|
|
18650
|
+
var TEMPLATE_BY_TYPE = {
|
|
18651
|
+
LESSON: "LESSON_5E_template.md",
|
|
18652
|
+
LESSON_5E: "LESSON_5E_template.md",
|
|
18653
|
+
LESSON_EDP: "LESSON_EDP_template.md",
|
|
18654
|
+
LESSON_GENERAL: "LESSON_GENERAL_template.md",
|
|
18655
|
+
ACT: "ACT_template.md",
|
|
18656
|
+
CODE: "CODE_template.md",
|
|
18657
|
+
// 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).
|
|
18659
|
+
CODE_LAB: "CODE_template.md",
|
|
18660
|
+
QUIZ: "QUIZ_v4.6_template.md",
|
|
18661
|
+
GUIDE: "GUIDE_template.md",
|
|
18662
|
+
HANDOUT: "HANDOUT_template.md",
|
|
18663
|
+
WKS: "WKS_template.md",
|
|
18664
|
+
EXT: "EXT_template.md",
|
|
18665
|
+
SLIDE: "SLIDE_template.md",
|
|
18666
|
+
KNOWLEDGE_EXPOSITION: "KNOWLEDGE_EXPOSITION_template.md",
|
|
18667
|
+
LEARNER_PROFILE: "LEARNER_PROFILE_template.md",
|
|
18668
|
+
PROJECT_BRIEF: "PROJECT_BRIEF_template.md",
|
|
18669
|
+
CURRICULUM_FRAMEWORK: "CURRICULUM_FRAMEWORK_template.md",
|
|
18670
|
+
CONTENT_STYLE_GUIDE: "CONTENT_STYLE_GUIDE_template.md",
|
|
18671
|
+
SECTION_LANGUAGE_CONTRACT: "SECTION_LANGUAGE_CONTRACT_template.md"
|
|
19070
18672
|
};
|
|
18673
|
+
function keepContractEntries(artifactType, mapping) {
|
|
18674
|
+
const templateFile = TEMPLATE_BY_TYPE[artifactType.trim().toUpperCase()];
|
|
18675
|
+
if (!templateFile) return mapping;
|
|
18676
|
+
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;
|
|
18684
|
+
}
|
|
19071
18685
|
function extractSectionHeadingsFromSLC(slcInput, artifactType, targetLanguage = "vi") {
|
|
19072
18686
|
const upperType = artifactType.trim().toUpperCase();
|
|
19073
18687
|
const getFallback = () => {
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
}
|
|
19080
|
-
}
|
|
19081
|
-
return {};
|
|
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]));
|
|
19082
18693
|
};
|
|
19083
18694
|
if (!slcInput) return getFallback();
|
|
19084
18695
|
if (typeof slcInput === "object") {
|
|
19085
|
-
if (slcInput[upperType] && Object.keys(slcInput[upperType]).length > 0)
|
|
18696
|
+
if (slcInput[upperType] && Object.keys(slcInput[upperType]).length > 0) {
|
|
18697
|
+
return keepContractEntries(upperType, slcInput[upperType]);
|
|
18698
|
+
}
|
|
19086
18699
|
for (const [key, mapping] of Object.entries(slcInput)) {
|
|
19087
18700
|
if (matchesArtifactType(key, upperType) && Object.keys(mapping).length > 0) {
|
|
19088
|
-
return mapping;
|
|
18701
|
+
return keepContractEntries(upperType, mapping);
|
|
19089
18702
|
}
|
|
19090
18703
|
}
|
|
19091
18704
|
return getFallback();
|
|
@@ -19113,24 +18726,33 @@ function extractSectionHeadingsFromSLC(slcInput, artifactType, targetLanguage =
|
|
|
19113
18726
|
}
|
|
19114
18727
|
}
|
|
19115
18728
|
}
|
|
19116
|
-
if (Object.keys(mapping).length > 0) return mapping;
|
|
18729
|
+
if (Object.keys(mapping).length > 0) return keepContractEntries(upperType, mapping);
|
|
19117
18730
|
}
|
|
19118
18731
|
}
|
|
19119
18732
|
return getFallback();
|
|
19120
18733
|
}
|
|
19121
|
-
function buildHeadingDirective(artifactType, slcMarkdown, targetLanguage = "vi") {
|
|
19122
|
-
const
|
|
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);
|
|
19123
18745
|
if (Object.keys(headings).length === 0) {
|
|
19124
18746
|
return "";
|
|
19125
18747
|
}
|
|
19126
18748
|
const lines = Object.entries(headings).map(
|
|
19127
|
-
([
|
|
18749
|
+
([heading, display]) => heading === display ? ` - "${display}"` : ` - "${heading}" -> Use Display Heading: "${display}"`
|
|
19128
18750
|
);
|
|
19129
|
-
return `MANDATORY SECTION HEADINGS
|
|
19130
|
-
-
|
|
19131
|
-
- In the markdown body, section headers MUST
|
|
18751
|
+
return `MANDATORY SECTION HEADINGS (SOURCE: RESOLVED ARTIFACT TEMPLATE):
|
|
18752
|
+
- Copy the template's YAML frontmatter \`template_required_sections\` list VERBATIM into the artifact frontmatter \u2014 never translate, reorder, or invent entries.
|
|
18753
|
+
- In the markdown body, section headers MUST be exactly the Display Headings below (do NOT translate, paraphrase, or re-marker them):
|
|
19132
18754
|
${lines.join("\n")}
|
|
19133
|
-
-
|
|
18755
|
+
- Example: if the resolved template's heading is "${Object.values(headings)[0]}", your body heading must be exactly "## ${Object.values(headings)[0]}".`;
|
|
19134
18756
|
}
|
|
19135
18757
|
|
|
19136
18758
|
// src/services/curriculumHorizon.ts
|
|
@@ -19777,53 +19399,9 @@ z.object({
|
|
|
19777
19399
|
assessmentMap: z.array(z.record(z.string())).default([]),
|
|
19778
19400
|
tieredScaffolding: z.object({ bronze: z.string().default(""), silver: z.string().default(""), gold: z.string().default("") }).default({ bronze: "", silver: "", gold: "" })
|
|
19779
19401
|
});
|
|
19780
|
-
|
|
19781
|
-
|
|
19782
|
-
|
|
19783
|
-
// Repo checkout layouts.
|
|
19784
|
-
"docs/refs/templates"
|
|
19785
|
-
];
|
|
19786
|
-
var _moduleDir = (() => {
|
|
19787
|
-
try {
|
|
19788
|
-
if (typeof import.meta !== "undefined" && typeof import.meta.url === "string") {
|
|
19789
|
-
return path.dirname(fileURLToPath(import.meta.url));
|
|
19790
|
-
}
|
|
19791
|
-
} catch {
|
|
19792
|
-
}
|
|
19793
|
-
return typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
19794
|
-
})();
|
|
19795
|
-
function candidateDirs(explicitDir) {
|
|
19796
|
-
const dirs = [];
|
|
19797
|
-
if (process.env.CURRICULUM_TEMPLATES_DIR) dirs.push(process.env.CURRICULUM_TEMPLATES_DIR);
|
|
19798
|
-
dirs.push(path.resolve(process.cwd(), "_templates"));
|
|
19799
|
-
for (const rel of KIT_TEMPLATE_FALLBACK_DIRS) {
|
|
19800
|
-
dirs.push(path.resolve(_moduleDir, rel));
|
|
19801
|
-
dirs.push(path.resolve(process.cwd(), rel));
|
|
19802
|
-
dirs.push(path.resolve(process.cwd(), "packages/curriculum-kit", rel));
|
|
19803
|
-
}
|
|
19804
|
-
return dirs;
|
|
19805
|
-
}
|
|
19806
|
-
function findTemplatePath(templateName, explicitDir) {
|
|
19807
|
-
for (const dir of candidateDirs()) {
|
|
19808
|
-
const p = path.join(dir, templateName);
|
|
19809
|
-
if (!fs5.existsSync(p)) continue;
|
|
19810
|
-
try {
|
|
19811
|
-
fs5.accessSync(p, fs5.constants.R_OK);
|
|
19812
|
-
return p;
|
|
19813
|
-
} catch {
|
|
19814
|
-
}
|
|
19815
|
-
}
|
|
19816
|
-
return null;
|
|
19817
|
-
}
|
|
19818
|
-
function loadCurriculumTemplate(templateName, templatesDir) {
|
|
19819
|
-
const p = findTemplatePath(templateName);
|
|
19820
|
-
if (!p) return "";
|
|
19821
|
-
try {
|
|
19822
|
-
return fs5.readFileSync(p, "utf-8");
|
|
19823
|
-
} catch {
|
|
19824
|
-
return "";
|
|
19825
|
-
}
|
|
19826
|
-
}
|
|
19402
|
+
|
|
19403
|
+
// src/services/lessonProductionService.ts
|
|
19404
|
+
init_templateLoader();
|
|
19827
19405
|
|
|
19828
19406
|
// src/services/singleArtifactService.ts
|
|
19829
19407
|
init_errors();
|