@thanh01.pmt/curriculum-kit 1.4.46 → 1.4.48
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/README.md +23 -0
- package/dist/ai/index.cjs +19 -1
- 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 +19 -1
- package/dist/ai/index.mjs.map +1 -1
- package/dist/index.cjs +199 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +98 -13
- package/dist/index.d.ts +98 -13
- package/dist/index.mjs +196 -9
- package/dist/index.mjs.map +1 -1
- package/dist/pipeline/index.cjs +19 -1
- package/dist/pipeline/index.cjs.map +1 -1
- package/dist/pipeline/index.mjs +19 -1
- package/dist/pipeline/index.mjs.map +1 -1
- package/dist/schemas/index.cjs +19 -1
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +1193 -1053
- package/dist/schemas/index.d.ts +1193 -1053
- package/dist/schemas/index.mjs +19 -1
- package/dist/schemas/index.mjs.map +1 -1
- 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/workflow/index.cjs +19 -1
- 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 +19 -1
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4019,7 +4019,25 @@ var PlanningNodeSchema = zod.z.object({
|
|
|
4019
4019
|
file: zod.z.string(),
|
|
4020
4020
|
evidence: zod.z.string().default("")
|
|
4021
4021
|
})).default([]),
|
|
4022
|
-
phase_id: zod.z.string().default("")
|
|
4022
|
+
phase_id: zod.z.string().default(""),
|
|
4023
|
+
// P52/T2.1: tangible user-visible outcome projected from the graph step
|
|
4024
|
+
// (checkpoint candidate for session cutting). Empty = not a checkpoint.
|
|
4025
|
+
user_visible_deliverable: zod.z.string().default(""),
|
|
4026
|
+
// P52/T3.1 — depth-reconcile inputs (mirrored from the feed; optional so
|
|
4027
|
+
// raw graphs without variants keep planning unchanged):
|
|
4028
|
+
// • depth_variants: minutes to teach this node at each depth level (ULO ≤
|
|
4029
|
+
// CIO ≤ SIO) — the reconciler's price list for downgrades.
|
|
4030
|
+
// • depth_scaffold_candidates: parallel to scaffold_candidates but acting
|
|
4031
|
+
// on DEPTH (SIO→CIO, CIO→ULO) instead of lesson time.
|
|
4032
|
+
// • is_core: Master-Tree core concept — never downgraded; escalate instead.
|
|
4033
|
+
depth_variants: zod.z.object({ ulo: zod.z.number().int().nonnegative(), cio: zod.z.number().int().nonnegative(), sio: zod.z.number().int().nonnegative() }).optional(),
|
|
4034
|
+
depth_scaffold_candidates: zod.z.array(zod.z.object({
|
|
4035
|
+
from_depth: DepthLevelSchema,
|
|
4036
|
+
to_depth: DepthLevelSchema,
|
|
4037
|
+
minutes_saved: zod.z.number().int().nonnegative(),
|
|
4038
|
+
reason: zod.z.string().default("")
|
|
4039
|
+
})).optional(),
|
|
4040
|
+
is_core: zod.z.boolean().default(false)
|
|
4023
4041
|
});
|
|
4024
4042
|
var DependencyEdgeSchema = zod.z.object({
|
|
4025
4043
|
from: zod.z.string(),
|
|
@@ -5436,6 +5454,7 @@ var MAX_NEW_CONCEPTS_PER_SESSION_K12 = 2;
|
|
|
5436
5454
|
var MAX_NEW_CONCEPTS_PER_SESSION_ADULT = 3;
|
|
5437
5455
|
var DEFAULT_OVERHEAD_RATIO = 0.15;
|
|
5438
5456
|
var MAX_IN_SESSION_SETUP_MINUTES = 15;
|
|
5457
|
+
var SESSION_CUT_TOLERANCE = 0.15;
|
|
5439
5458
|
var ENVIRONMENT_PROVISIONING_MODELS = [
|
|
5440
5459
|
"PRE_INSTALLED_LAB",
|
|
5441
5460
|
"CLOUD_MANAGED",
|
|
@@ -10547,6 +10566,98 @@ async function ensureExpositionForLesson(storage, projectId, lessonCode, options
|
|
|
10547
10566
|
return { relPath: result.relPath, context: buildExpositionContext(result.content), reused: result.reused, rawContent: result.content };
|
|
10548
10567
|
}
|
|
10549
10568
|
init_errors();
|
|
10569
|
+
|
|
10570
|
+
// src/services/depthReconciler.ts
|
|
10571
|
+
function tierOf(node, isLeaf) {
|
|
10572
|
+
if (node.phase_id !== "" && /__ADV\d{2}$/.test(node.id)) return 1;
|
|
10573
|
+
const depth = node.depth_hint ?? "cio";
|
|
10574
|
+
if (depth === "sio") return isLeaf ? 2 : 3;
|
|
10575
|
+
if (depth === "cio") return isLeaf ? 4 : 5;
|
|
10576
|
+
return -1;
|
|
10577
|
+
}
|
|
10578
|
+
function classifyDepthCandidates(nodes, edges) {
|
|
10579
|
+
const baseConcept = (id) => id.replace(/__(ADV|PREV)\d{2}$/, "");
|
|
10580
|
+
const conceptIds = new Set(nodes.filter((n) => n.kind === "concept").map((n) => baseConcept(n.id)));
|
|
10581
|
+
const hasDependent = /* @__PURE__ */ new Set();
|
|
10582
|
+
for (const e of edges) {
|
|
10583
|
+
if (e.kind !== "knowledge") continue;
|
|
10584
|
+
const from = baseConcept(e.from);
|
|
10585
|
+
const to = baseConcept(e.to);
|
|
10586
|
+
if (conceptIds.has(from) && conceptIds.has(to)) hasDependent.add(from);
|
|
10587
|
+
}
|
|
10588
|
+
const isLeaf = /* @__PURE__ */ new Map();
|
|
10589
|
+
for (const n of nodes) {
|
|
10590
|
+
if (n.kind !== "concept") continue;
|
|
10591
|
+
const base = baseConcept(n.id);
|
|
10592
|
+
if (!isLeaf.has(base)) isLeaf.set(base, !hasDependent.has(base));
|
|
10593
|
+
}
|
|
10594
|
+
return isLeaf;
|
|
10595
|
+
}
|
|
10596
|
+
function reconcilePlanDepth(nodes, edges, spec, budgetMinutes) {
|
|
10597
|
+
const MAX_ROUNDS = 5;
|
|
10598
|
+
const total = () => nodes.reduce((acc, n) => acc + n.estimated_minutes, 0);
|
|
10599
|
+
const isLeaf = classifyDepthCandidates(nodes, edges);
|
|
10600
|
+
const baseConcept = (id) => id.replace(/__(ADV|PREV)\d{2}$/, "");
|
|
10601
|
+
const applied = [];
|
|
10602
|
+
const mutated = /* @__PURE__ */ new Set();
|
|
10603
|
+
let rounds = 0;
|
|
10604
|
+
while (total() > budgetMinutes && rounds < MAX_ROUNDS) {
|
|
10605
|
+
rounds++;
|
|
10606
|
+
let overBy = total() - budgetMinutes;
|
|
10607
|
+
const candidates = [];
|
|
10608
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
10609
|
+
const n = nodes[i];
|
|
10610
|
+
if (n.kind !== "concept") continue;
|
|
10611
|
+
if (n.is_core) continue;
|
|
10612
|
+
if (n.depth_hint == null) continue;
|
|
10613
|
+
const base = baseConcept(n.id);
|
|
10614
|
+
const leaf = isLeaf.get(base) ?? true;
|
|
10615
|
+
const tier = tierOf(n, leaf);
|
|
10616
|
+
if (tier < 0) continue;
|
|
10617
|
+
const depth = n.depth_hint ?? "cio";
|
|
10618
|
+
const toDepth = depth === "sio" ? "cio" : "ulo";
|
|
10619
|
+
const variants = n.depth_variants;
|
|
10620
|
+
const target = variants ? variants[toDepth] : Math.max(5, Math.round(n.estimated_minutes * 0.6));
|
|
10621
|
+
const saved = n.estimated_minutes - target;
|
|
10622
|
+
if (saved <= 0) continue;
|
|
10623
|
+
candidates.push({
|
|
10624
|
+
nodeId: n.id,
|
|
10625
|
+
fromDepth: depth,
|
|
10626
|
+
toDepth,
|
|
10627
|
+
minutesSaved: saved,
|
|
10628
|
+
reason: n.depth_scaffold_candidates?.find((c) => c.to_depth === toDepth)?.reason ?? `depth downgrade ${depth}\u2192${toDepth} (tier ${tier}${leaf ? ", leaf" : ""})`,
|
|
10629
|
+
node: n,
|
|
10630
|
+
tier,
|
|
10631
|
+
index: i
|
|
10632
|
+
});
|
|
10633
|
+
}
|
|
10634
|
+
if (candidates.length === 0) break;
|
|
10635
|
+
candidates.sort((a, b) => a.tier - b.tier || b.minutesSaved - a.minutesSaved);
|
|
10636
|
+
for (const c of candidates) {
|
|
10637
|
+
if (overBy <= 0) break;
|
|
10638
|
+
const n = c.node;
|
|
10639
|
+
const target = n.depth_variants ? n.depth_variants[c.toDepth] : Math.max(5, Math.round(n.estimated_minutes * 0.6));
|
|
10640
|
+
const saved = n.estimated_minutes - target;
|
|
10641
|
+
if (saved <= 0) continue;
|
|
10642
|
+
n.estimated_minutes = target;
|
|
10643
|
+
n.depth_hint = c.toDepth;
|
|
10644
|
+
applied.push({ nodeId: n.id, fromDepth: c.fromDepth, toDepth: c.toDepth, minutesSaved: saved, reason: c.reason });
|
|
10645
|
+
mutated.add(n.id);
|
|
10646
|
+
overBy -= saved;
|
|
10647
|
+
}
|
|
10648
|
+
}
|
|
10649
|
+
const finalTotal = total();
|
|
10650
|
+
const deficitMinutes = Math.max(0, finalTotal - budgetMinutes);
|
|
10651
|
+
return {
|
|
10652
|
+
unchanged: applied.length === 0,
|
|
10653
|
+
applied,
|
|
10654
|
+
mutatedNodeIds: [...mutated],
|
|
10655
|
+
escalate: deficitMinutes > 0,
|
|
10656
|
+
deficitMinutes
|
|
10657
|
+
};
|
|
10658
|
+
}
|
|
10659
|
+
|
|
10660
|
+
// src/services/curriculumPlannerService.ts
|
|
10550
10661
|
var asArr = (v) => Array.isArray(v) ? v : [];
|
|
10551
10662
|
var asStr = (v, dflt = "") => typeof v === "string" ? v : dflt;
|
|
10552
10663
|
var asNum = (v, dflt) => typeof v === "number" && Number.isFinite(v) ? v : dflt;
|
|
@@ -10586,7 +10697,20 @@ function normalizePlanningGraph(raw) {
|
|
|
10586
10697
|
suggest: asStr(c.suggest, "provide_full")
|
|
10587
10698
|
})),
|
|
10588
10699
|
references: asArr(n.references).map((ref) => ({ file: asStr(ref.file), evidence: asStr(ref.evidence) })).filter((ref) => ref.file),
|
|
10589
|
-
phase_id: asStr(n.phase_id)
|
|
10700
|
+
phase_id: asStr(n.phase_id),
|
|
10701
|
+
user_visible_deliverable: asStr(n.user_visible_deliverable),
|
|
10702
|
+
depth_variants: (() => {
|
|
10703
|
+
const dv = n.depth_variants;
|
|
10704
|
+
if (!dv) return void 0;
|
|
10705
|
+
return { ulo: Math.max(0, Math.round(asNum(dv.ulo, 0))), cio: Math.max(0, Math.round(asNum(dv.cio, 0))), sio: Math.max(0, Math.round(asNum(dv.sio, 0))) };
|
|
10706
|
+
})(),
|
|
10707
|
+
depth_scaffold_candidates: asArr(n.depth_scaffold_candidates).map((c) => ({
|
|
10708
|
+
from_depth: asStr(c.from_depth, "sio"),
|
|
10709
|
+
to_depth: asStr(c.to_depth, "cio"),
|
|
10710
|
+
minutes_saved: Math.max(0, Math.round(asNum(c.minutes_saved, 0))),
|
|
10711
|
+
reason: asStr(c.reason)
|
|
10712
|
+
})),
|
|
10713
|
+
is_core: n.is_core === true
|
|
10590
10714
|
});
|
|
10591
10715
|
}
|
|
10592
10716
|
for (const e of asArr(r.dependency_edges)) {
|
|
@@ -10630,7 +10754,9 @@ function normalizePlanningGraph(raw) {
|
|
|
10630
10754
|
completion_level: "standard",
|
|
10631
10755
|
scaffold_candidates: [],
|
|
10632
10756
|
references: [],
|
|
10633
|
-
phase_id: ""
|
|
10757
|
+
phase_id: "",
|
|
10758
|
+
user_visible_deliverable: "",
|
|
10759
|
+
is_core: false
|
|
10634
10760
|
});
|
|
10635
10761
|
for (const p of asStrArr(c.prerequisites)) {
|
|
10636
10762
|
edges.push({ from: p, to: asStr(c.id), kind: "knowledge", reason: "concept prerequisite" });
|
|
@@ -10667,7 +10793,9 @@ function normalizePlanningGraph(raw) {
|
|
|
10667
10793
|
completion_level: "standard",
|
|
10668
10794
|
scaffold_candidates: [],
|
|
10669
10795
|
references: [],
|
|
10670
|
-
phase_id: ""
|
|
10796
|
+
phase_id: "",
|
|
10797
|
+
user_visible_deliverable: "",
|
|
10798
|
+
is_core: false
|
|
10671
10799
|
});
|
|
10672
10800
|
if (prev) edges.push({ from: prev, to: id, kind: "task", reason: "roadmap sequence" });
|
|
10673
10801
|
prev = id;
|
|
@@ -10703,13 +10831,15 @@ function normalizePlanningGraph(raw) {
|
|
|
10703
10831
|
completion_level: "standard",
|
|
10704
10832
|
scaffold_candidates: [],
|
|
10705
10833
|
references: [],
|
|
10706
|
-
phase_id: ""
|
|
10834
|
+
phase_id: "",
|
|
10835
|
+
user_visible_deliverable: "",
|
|
10836
|
+
is_core: false
|
|
10707
10837
|
});
|
|
10708
10838
|
if (prev) edges.push({ from: prev, to: id, kind: "task", reason: "feature build order" });
|
|
10709
10839
|
prev = id;
|
|
10710
10840
|
}
|
|
10711
10841
|
if (stepCount === 0 && fid) {
|
|
10712
|
-
nodes.push({ id: fid, kind: "skill", name: asStr(f.name, fid), concept_codes: [], keywords: [], new_keywords: [], prerequisite_keywords: [], estimated_minutes: 45, bloom_hint: "Apply", depth_hint: null, completion_level: "standard", scaffold_candidates: [], references: [], phase_id: "" });
|
|
10842
|
+
nodes.push({ id: fid, kind: "skill", name: asStr(f.name, fid), concept_codes: [], keywords: [], new_keywords: [], prerequisite_keywords: [], estimated_minutes: 45, bloom_hint: "Apply", depth_hint: null, completion_level: "standard", scaffold_candidates: [], references: [], phase_id: "", user_visible_deliverable: "", is_core: false });
|
|
10713
10843
|
}
|
|
10714
10844
|
}
|
|
10715
10845
|
}
|
|
@@ -10871,6 +11001,39 @@ function computePackingSpec(constraints) {
|
|
|
10871
11001
|
sessionDurationMinutes: constraints.session_duration_minutes
|
|
10872
11002
|
};
|
|
10873
11003
|
}
|
|
11004
|
+
var filledOf = (s) => s.knowledgeMinutes + s.practiceMinutes;
|
|
11005
|
+
function cutBackToCheckpoint(current, nodeById, spec, warnings) {
|
|
11006
|
+
const budget = spec.contentBudget;
|
|
11007
|
+
const minFill = budget * (1 - SESSION_CUT_TOLERANCE);
|
|
11008
|
+
const hasPartAfter = new Array(current.entries.length).fill(false);
|
|
11009
|
+
let seenPart = false;
|
|
11010
|
+
for (let i = current.entries.length - 1; i >= 0; i--) {
|
|
11011
|
+
hasPartAfter[i] = seenPart;
|
|
11012
|
+
if (current.entries[i].totalParts > 1) seenPart = true;
|
|
11013
|
+
}
|
|
11014
|
+
let bestIdx = -1;
|
|
11015
|
+
let cumulative = 0;
|
|
11016
|
+
for (let i = 0; i < current.entries.length; i++) {
|
|
11017
|
+
const e = current.entries[i];
|
|
11018
|
+
cumulative += e.minutes;
|
|
11019
|
+
if (hasPartAfter[i] || e.totalParts > 1) continue;
|
|
11020
|
+
const n = nodeById.get(e.id);
|
|
11021
|
+
if (!n || n.user_visible_deliverable.trim().length === 0) continue;
|
|
11022
|
+
if (cumulative > budget || cumulative < minFill) continue;
|
|
11023
|
+
bestIdx = i;
|
|
11024
|
+
}
|
|
11025
|
+
if (bestIdx < 0) {
|
|
11026
|
+
warnings.push("no-checkpoint-within-tolerance: session cut at " + filledOf(current) + "m without a user-visible deliverable");
|
|
11027
|
+
return [];
|
|
11028
|
+
}
|
|
11029
|
+
const displacedEntries = current.entries.splice(bestIdx + 1);
|
|
11030
|
+
for (const e of displacedEntries) {
|
|
11031
|
+
if (nodeById.get(e.id)?.kind === "concept") current.knowledgeMinutes -= e.minutes;
|
|
11032
|
+
else current.practiceMinutes -= e.minutes;
|
|
11033
|
+
}
|
|
11034
|
+
current.nodeIds = current.entries.map((e) => e.id);
|
|
11035
|
+
return displacedEntries.map((e) => nodeById.get(e.id)).filter((n) => n != null);
|
|
11036
|
+
}
|
|
10874
11037
|
function packUnitSessions(group, nodeById, spec, warnings) {
|
|
10875
11038
|
const sessions = [];
|
|
10876
11039
|
const fresh = () => ({ groupId: group.key, nodeIds: [], entries: [], knowledgeMinutes: 0, practiceMinutes: 0, oversized: false });
|
|
@@ -10880,7 +11043,9 @@ function packUnitSessions(group, nodeById, spec, warnings) {
|
|
|
10880
11043
|
current = fresh();
|
|
10881
11044
|
};
|
|
10882
11045
|
const filled = () => current.knowledgeMinutes + current.practiceMinutes;
|
|
10883
|
-
|
|
11046
|
+
const ids = [...group.orderedIds];
|
|
11047
|
+
while (ids.length > 0) {
|
|
11048
|
+
const id = ids.shift();
|
|
10884
11049
|
const node = nodeById.get(id);
|
|
10885
11050
|
const isKnowledge = node.kind === "concept";
|
|
10886
11051
|
if (node.estimated_minutes > spec.contentBudget) {
|
|
@@ -10916,7 +11081,16 @@ function packUnitSessions(group, nodeById, spec, warnings) {
|
|
|
10916
11081
|
continue;
|
|
10917
11082
|
}
|
|
10918
11083
|
const minutes = node.estimated_minutes;
|
|
10919
|
-
if (current.entries.length > 0 && filled() + minutes > spec.contentBudget)
|
|
11084
|
+
if (current.entries.length > 0 && filled() + minutes > spec.contentBudget) {
|
|
11085
|
+
const displaced = cutBackToCheckpoint(current, nodeById, spec, warnings);
|
|
11086
|
+
if (displaced.length > 0) {
|
|
11087
|
+
ids.unshift(id);
|
|
11088
|
+
for (let di = displaced.length - 1; di >= 0; di--) ids.unshift(displaced[di].id);
|
|
11089
|
+
flush();
|
|
11090
|
+
continue;
|
|
11091
|
+
}
|
|
11092
|
+
flush();
|
|
11093
|
+
}
|
|
10920
11094
|
if (isKnowledge) current.knowledgeMinutes += minutes;
|
|
10921
11095
|
else current.practiceMinutes += minutes;
|
|
10922
11096
|
current.entries.push({ id, minutes, part: 1, totalParts: 1 });
|
|
@@ -11226,6 +11400,19 @@ async function buildCurriculumPlan(rawGraph, options) {
|
|
|
11226
11400
|
const graph = normalizePlanningGraph(rawGraph);
|
|
11227
11401
|
warnings.push(...graph.warnings);
|
|
11228
11402
|
assertAcyclic(graph.nodes, graph.edges);
|
|
11403
|
+
let reconcileSummary = null;
|
|
11404
|
+
if (typeof constraints.total_sessions === "number" && constraints.total_sessions > 0) {
|
|
11405
|
+
const spec0 = computePackingSpec(constraints);
|
|
11406
|
+
const budgetMinutes = constraints.total_sessions * spec0.contentBudget;
|
|
11407
|
+
reconcileSummary = reconcilePlanDepth(graph.nodes, graph.edges, spec0, budgetMinutes);
|
|
11408
|
+
if (!reconcileSummary.unchanged) {
|
|
11409
|
+
const saved = reconcileSummary.applied.reduce((a, x) => a + x.minutesSaved, 0);
|
|
11410
|
+
warnings.push(`depth reconcile: ${reconcileSummary.applied.length} downgrade(s), saved ${saved}m across ${reconcileSummary.mutatedNodeIds.length} node(s)`);
|
|
11411
|
+
}
|
|
11412
|
+
if (reconcileSummary.escalate) {
|
|
11413
|
+
warnings.push(`budget_escalation: deficit ${reconcileSummary.deficitMinutes}m after exhausting non-core depth candidates (budget ${constraints.total_sessions * computePackingSpec(constraints).contentBudget}m) \u2014 human review required`);
|
|
11414
|
+
}
|
|
11415
|
+
}
|
|
11229
11416
|
const orderedIds = topoSort(graph.nodes, graph.edges);
|
|
11230
11417
|
const nodeById = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
11231
11418
|
const spec = computePackingSpec(constraints);
|
|
@@ -31673,6 +31860,7 @@ exports.RotationStationSchema = RotationStationSchema;
|
|
|
31673
31860
|
exports.RubricCriteriaSchema = RubricCriteriaSchema;
|
|
31674
31861
|
exports.RubricSchema = RubricSchema;
|
|
31675
31862
|
exports.SATELLITE_LESSON_PRIORITIES = SATELLITE_LESSON_PRIORITIES;
|
|
31863
|
+
exports.SESSION_CUT_TOLERANCE = SESSION_CUT_TOLERANCE;
|
|
31676
31864
|
exports.SLIDE_CANONICAL_METHODOLOGY = SLIDE_CANONICAL_METHODOLOGY;
|
|
31677
31865
|
exports.STANDARD_REF_REGEX = STANDARD_REF_REGEX;
|
|
31678
31866
|
exports.STANDARD_SOT_FILES = STANDARD_SOT_FILES;
|
|
@@ -31762,6 +31950,7 @@ exports.buildTeacherGuidePrompt = buildTeacherGuidePrompt;
|
|
|
31762
31950
|
exports.buildWalkingSkeleton = buildWalkingSkeleton;
|
|
31763
31951
|
exports.buildWorksheetPrompt = buildWorksheetPrompt;
|
|
31764
31952
|
exports.checkSessionZpd = checkSessionZpd;
|
|
31953
|
+
exports.classifyDepthCandidates = classifyDepthCandidates;
|
|
31765
31954
|
exports.closeTruncatedJson = closeTruncatedJson;
|
|
31766
31955
|
exports.computeConceptSpiralProgression = computeConceptSpiralProgression;
|
|
31767
31956
|
exports.computeContentHash = computeContentHash;
|
|
@@ -31855,6 +32044,7 @@ exports.loadAuthoringTemplate = loadAuthoringTemplate;
|
|
|
31855
32044
|
exports.loadCurriculumTemplate = loadCurriculumTemplate;
|
|
31856
32045
|
exports.loadSotTemplate = loadSotTemplate;
|
|
31857
32046
|
exports.normalizePlanningGraph = normalizePlanningGraph;
|
|
32047
|
+
exports.packUnitSessions = packUnitSessions;
|
|
31858
32048
|
exports.packagerTools = packagerTools;
|
|
31859
32049
|
exports.parseAllSessions = parseAllSessions;
|
|
31860
32050
|
exports.parseGateSettings = parseGateSettings;
|
|
@@ -31865,6 +32055,7 @@ exports.produceSingleLesson = produceSingleLesson;
|
|
|
31865
32055
|
exports.publishToGitHub = publishToGitHub;
|
|
31866
32056
|
exports.publishToSupabase = publishToSupabase;
|
|
31867
32057
|
exports.rankGenCandidates = rankGenCandidates;
|
|
32058
|
+
exports.reconcilePlanDepth = reconcilePlanDepth;
|
|
31868
32059
|
exports.renderAssignedRowsTable = renderAssignedRowsTable;
|
|
31869
32060
|
exports.renderEntitySlotsForType = renderEntitySlotsForType;
|
|
31870
32061
|
exports.renderFrameworkFromPlan = renderFrameworkFromPlan;
|