@thanh01.pmt/curriculum-kit 1.4.42 → 1.4.44
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.mjs +64 -469
- package/dist/ai/index.mjs.map +1 -1
- package/dist/index.cjs +237 -688
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -31
- package/dist/index.d.ts +12 -31
- package/dist/index.mjs +235 -682
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +66 -470
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +64 -469
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/templates/LAB_TEMPLATE.md +61 -0
- package/dist/templates/SELF_LAB_template.md +167 -0
- package/dist/workflow/index.cjs +84 -528
- package/dist/workflow/index.cjs.map +1 -1
- package/dist/workflow/index.mjs +82 -526
- package/dist/workflow/index.mjs.map +1 -1
- package/docs/refs/templates/LAB_TEMPLATE.md +61 -0
- package/docs/refs/templates/SELF_LAB_template.md +167 -0
- 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
6
|
import { generateObject } from 'ai';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
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 + "=")) {
|
|
@@ -2744,467 +2744,70 @@ z.object({
|
|
|
2744
2744
|
}),
|
|
2745
2745
|
phases: z.array(PhaseInputSchema).default([])
|
|
2746
2746
|
});
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
---
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
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();
|
|
2747
|
+
function stripTemplateFrontmatter(raw) {
|
|
2748
|
+
let body = raw;
|
|
2749
|
+
if (body.startsWith("---")) {
|
|
2750
|
+
const end = body.indexOf("\n---", 3);
|
|
2751
|
+
if (end !== -1) body = body.slice(end + 4);
|
|
2752
|
+
}
|
|
2753
|
+
return body.split("\n").filter((l) => l.trim() !== "<!-- INJECT_BODY -->").join("\n").replace(/^\s*\n/, "").trimEnd();
|
|
2754
|
+
}
|
|
2755
|
+
var KIT_TEMPLATE_FALLBACK_DIRS = [
|
|
2756
|
+
// Packaged with the npm bundle (dist/templates) — resolves from node_modules.
|
|
2757
|
+
"templates",
|
|
2758
|
+
// Repo checkout layouts.
|
|
2759
|
+
"docs/refs/templates"
|
|
2760
|
+
];
|
|
2761
|
+
var _moduleDir = (() => {
|
|
2762
|
+
try {
|
|
2763
|
+
if (typeof import.meta !== "undefined" && typeof import.meta.url === "string") {
|
|
2764
|
+
return path.dirname(fileURLToPath(import.meta.url));
|
|
2765
|
+
}
|
|
2766
|
+
} catch {
|
|
2767
|
+
}
|
|
2768
|
+
return typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
2769
|
+
})();
|
|
2770
|
+
function candidateDirs(explicitDir) {
|
|
2771
|
+
const dirs = [];
|
|
2772
|
+
if (process.env.CURRICULUM_TEMPLATES_DIR) dirs.push(process.env.CURRICULUM_TEMPLATES_DIR);
|
|
2773
|
+
dirs.push(path.resolve(process.cwd(), "_templates"));
|
|
2774
|
+
for (const rel of KIT_TEMPLATE_FALLBACK_DIRS) {
|
|
2775
|
+
dirs.push(path.resolve(_moduleDir, rel));
|
|
2776
|
+
dirs.push(path.resolve(process.cwd(), rel));
|
|
2777
|
+
dirs.push(path.resolve(process.cwd(), "packages/curriculum-kit", rel));
|
|
2778
|
+
}
|
|
2779
|
+
return dirs;
|
|
2780
|
+
}
|
|
2781
|
+
function findTemplatePath(templateName, explicitDir) {
|
|
2782
|
+
for (const dir of candidateDirs()) {
|
|
2783
|
+
const p = path.join(dir, templateName);
|
|
2784
|
+
if (!fs2.existsSync(p)) continue;
|
|
2785
|
+
try {
|
|
2786
|
+
fs2.accessSync(p, fs2.constants.R_OK);
|
|
2787
|
+
return p;
|
|
2788
|
+
} catch {
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
return null;
|
|
2792
|
+
}
|
|
2793
|
+
function loadCurriculumTemplate(templateName, templatesDir) {
|
|
2794
|
+
const p = findTemplatePath(templateName);
|
|
2795
|
+
if (!p) return "";
|
|
2796
|
+
try {
|
|
2797
|
+
return fs2.readFileSync(p, "utf-8");
|
|
2798
|
+
} catch {
|
|
2799
|
+
return "";
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
function loadAuthoringTemplate(templateName, templatesDir) {
|
|
2803
|
+
const p = findTemplatePath(templateName);
|
|
2804
|
+
if (!p) return "";
|
|
2805
|
+
try {
|
|
2806
|
+
return stripTemplateFrontmatter(fs2.readFileSync(p, "utf-8"));
|
|
2807
|
+
} catch {
|
|
2808
|
+
return "";
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
3208
2811
|
|
|
3209
2812
|
// src/ai/prompts/lessonMasterPrompt.ts
|
|
3210
2813
|
function buildLessonMasterPrompt(input) {
|
|
@@ -3258,7 +2861,7 @@ Build a deep, rigorous, and highly pedagogical Master Lesson Plan (LESSON) that
|
|
|
3258
2861
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3259
2862
|
You MUST generate structured data that will render directly into this exact Markdown template:
|
|
3260
2863
|
---
|
|
3261
|
-
${
|
|
2864
|
+
${loadAuthoringTemplate("LESSON_5E_template.md") ?? "[TEMPLATE FILE NOT FOUND: LESSON_5E_template.md]"}
|
|
3262
2865
|
---
|
|
3263
2866
|
|
|
3264
2867
|
# INPUT PARAMETERS
|
|
@@ -3336,7 +2939,7 @@ Transform the exact pedagogical flow and activities from the Master Lesson Plan
|
|
|
3336
2939
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3337
2940
|
You MUST generate data aligned with this Markdown template:
|
|
3338
2941
|
---
|
|
3339
|
-
${
|
|
2942
|
+
${loadAuthoringTemplate("ACT_template.md") ?? "[TEMPLATE FILE NOT FOUND: ACT_template.md]"}
|
|
3340
2943
|
---
|
|
3341
2944
|
|
|
3342
2945
|
# CANONICAL MASTER LESSON CONTEXT (SOURCE OF TRUTH)
|
|
@@ -3431,7 +3034,7 @@ Generate complete, verified source code that satisfies the lesson objectives and
|
|
|
3431
3034
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3432
3035
|
You MUST generate data aligned with this Markdown template:
|
|
3433
3036
|
---
|
|
3434
|
-
${
|
|
3037
|
+
${loadAuthoringTemplate("LAB_TEMPLATE.md") ?? "[TEMPLATE FILE NOT FOUND: LAB_TEMPLATE.md]"}
|
|
3435
3038
|
---
|
|
3436
3039
|
|
|
3437
3040
|
# CANONICAL LESSON CONTEXT (SOURCE OF TRUTH)
|
|
@@ -3843,7 +3446,7 @@ Build a complete, engaging Self-Paced Hands-On Lab (SELF_LAB) for autonomous lea
|
|
|
3843
3446
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3844
3447
|
You MUST generate data aligned with this Markdown template:
|
|
3845
3448
|
---
|
|
3846
|
-
${
|
|
3449
|
+
${loadAuthoringTemplate("SELF_LAB_template.md") ?? "[TEMPLATE FILE NOT FOUND: SELF_LAB_template.md]"}
|
|
3847
3450
|
---
|
|
3848
3451
|
|
|
3849
3452
|
# INPUT PARAMETERS
|
|
@@ -3980,7 +3583,7 @@ Use this mapping to determine which Bloom level each question truly targets. Mat
|
|
|
3980
3583
|
# MANDATORY TEMPLATE STRUCTURE
|
|
3981
3584
|
You MUST generate data aligned with this Markdown template:
|
|
3982
3585
|
---
|
|
3983
|
-
${
|
|
3586
|
+
${loadAuthoringTemplate("QUIZ_v4.6_template.md") ?? "[TEMPLATE FILE NOT FOUND: QUIZ_v4.6_template.md]"}
|
|
3984
3587
|
---
|
|
3985
3588
|
|
|
3986
3589
|
# INPUT PARAMETERS
|
|
@@ -4963,7 +4566,7 @@ var LocalWorkspaceManager = class {
|
|
|
4963
4566
|
}
|
|
4964
4567
|
async initJobWorkspace(jobId, initialInfo) {
|
|
4965
4568
|
const jobDir = this.getJobDirectory(jobId);
|
|
4966
|
-
await
|
|
4569
|
+
await fs3.mkdir(jobDir, { recursive: true });
|
|
4967
4570
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4968
4571
|
const manifest = {
|
|
4969
4572
|
jobId,
|
|
@@ -4983,10 +4586,10 @@ var LocalWorkspaceManager = class {
|
|
|
4983
4586
|
async saveArtifact(jobId, milestoneSlug, filename, content, artifactType) {
|
|
4984
4587
|
const jobDir = this.getJobDirectory(jobId);
|
|
4985
4588
|
const targetDir = path.join(jobDir, milestoneSlug);
|
|
4986
|
-
await
|
|
4589
|
+
await fs3.mkdir(targetDir, { recursive: true });
|
|
4987
4590
|
const filePath = path.join(targetDir, filename);
|
|
4988
|
-
await
|
|
4989
|
-
const stat = await
|
|
4591
|
+
await fs3.writeFile(filePath, content, "utf-8");
|
|
4592
|
+
const stat = await fs3.stat(filePath);
|
|
4990
4593
|
const manifest = await this.getManifest(jobId);
|
|
4991
4594
|
if (manifest) {
|
|
4992
4595
|
manifest.artifacts.push({
|
|
@@ -5004,7 +4607,7 @@ var LocalWorkspaceManager = class {
|
|
|
5004
4607
|
async getManifest(jobId) {
|
|
5005
4608
|
const manifestPath = path.join(this.getJobDirectory(jobId), "manifest.json");
|
|
5006
4609
|
try {
|
|
5007
|
-
const data = await
|
|
4610
|
+
const data = await fs3.readFile(manifestPath, "utf-8");
|
|
5008
4611
|
return JSON.parse(data);
|
|
5009
4612
|
} catch {
|
|
5010
4613
|
return null;
|
|
@@ -5013,7 +4616,7 @@ var LocalWorkspaceManager = class {
|
|
|
5013
4616
|
async saveManifest(jobId, manifest) {
|
|
5014
4617
|
const manifestPath = path.join(this.getJobDirectory(jobId), "manifest.json");
|
|
5015
4618
|
manifest.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5016
|
-
await
|
|
4619
|
+
await fs3.writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
5017
4620
|
}
|
|
5018
4621
|
async markMilestoneCompleted(jobId) {
|
|
5019
4622
|
const manifest = await this.getManifest(jobId);
|
|
@@ -5050,13 +4653,13 @@ async function publishToGitHub(options) {
|
|
|
5050
4653
|
try {
|
|
5051
4654
|
const filesToUpload = [];
|
|
5052
4655
|
async function scanDir(currentDir) {
|
|
5053
|
-
const entries = await
|
|
4656
|
+
const entries = await fs3.readdir(currentDir, { withFileTypes: true });
|
|
5054
4657
|
for (const entry of entries) {
|
|
5055
4658
|
const fullPath = path.join(currentDir, entry.name);
|
|
5056
4659
|
if (entry.isDirectory()) {
|
|
5057
4660
|
await scanDir(fullPath);
|
|
5058
4661
|
} else if (entry.isFile() && !entry.name.startsWith(".")) {
|
|
5059
|
-
const content = await
|
|
4662
|
+
const content = await fs3.readFile(fullPath, "utf-8");
|
|
5060
4663
|
const relPath = path.relative(options.localJobDir, fullPath);
|
|
5061
4664
|
filesToUpload.push({ path: relPath, content });
|
|
5062
4665
|
}
|
|
@@ -19777,53 +19380,6 @@ z.object({
|
|
|
19777
19380
|
assessmentMap: z.array(z.record(z.string())).default([]),
|
|
19778
19381
|
tieredScaffolding: z.object({ bronze: z.string().default(""), silver: z.string().default(""), gold: z.string().default("") }).default({ bronze: "", silver: "", gold: "" })
|
|
19779
19382
|
});
|
|
19780
|
-
var KIT_TEMPLATE_FALLBACK_DIRS = [
|
|
19781
|
-
// Packaged with the npm bundle (dist/templates) — resolves from node_modules.
|
|
19782
|
-
"templates",
|
|
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
|
-
}
|
|
19827
19383
|
|
|
19828
19384
|
// src/services/singleArtifactService.ts
|
|
19829
19385
|
init_errors();
|