@thanh01.pmt/presentation-kit 0.2.15 → 0.2.16
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 +145 -16
- package/dist/ai/index.cjs.map +1 -1
- package/dist/ai/index.d.cts +15 -15
- package/dist/ai/index.d.ts +15 -15
- package/dist/ai/index.js +132 -3
- package/dist/ai/index.js.map +1 -1
- package/dist/{chunk-YPYAP4TF.js → chunk-7QHDWDSB.js} +218 -4
- package/dist/chunk-7QHDWDSB.js.map +1 -0
- package/dist/{chunk-SUGKWGJJ.cjs → chunk-JNTRKKJX.cjs} +218 -3
- package/dist/chunk-JNTRKKJX.cjs.map +1 -0
- package/dist/index.cjs +19 -15
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -2
- package/dist/react/index.cjs +5 -5
- package/dist/react/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-SUGKWGJJ.cjs.map +0 -1
- package/dist/chunk-YPYAP4TF.js.map +0 -1
package/dist/ai/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkJNTRKKJX_cjs = require('../chunk-JNTRKKJX.cjs');
|
|
4
4
|
var zod = require('zod');
|
|
5
5
|
|
|
6
6
|
var listSlidePresetsSchema = zod.z.object({
|
|
@@ -64,7 +64,7 @@ var generateDeckOutlineSchema = zod.z.object({
|
|
|
64
64
|
// src/ai/tools.ts
|
|
65
65
|
function executeListSlidePresets(params) {
|
|
66
66
|
const category = params?.category;
|
|
67
|
-
const presets = !category || category === "all" ?
|
|
67
|
+
const presets = !category || category === "all" ? chunkJNTRKKJX_cjs.SLIDE_LAYOUT_PRESETS : chunkJNTRKKJX_cjs.getSlideLayoutPresetsByCategory(category);
|
|
68
68
|
return {
|
|
69
69
|
count: presets.length,
|
|
70
70
|
presets: presets.map((p) => ({
|
|
@@ -78,7 +78,7 @@ function executeListSlidePresets(params) {
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
function executeCreateSlideFromPreset(params) {
|
|
81
|
-
const preset =
|
|
81
|
+
const preset = chunkJNTRKKJX_cjs.getSlideLayoutPresetById(params.presetId);
|
|
82
82
|
if (!preset) {
|
|
83
83
|
return {
|
|
84
84
|
success: false,
|
|
@@ -86,7 +86,7 @@ function executeCreateSlideFromPreset(params) {
|
|
|
86
86
|
error: `Preset with ID "${params.presetId}" not found. Use listSlidePresets to see available layout templates.`
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
-
const layoutComment =
|
|
89
|
+
const layoutComment = chunkJNTRKKJX_cjs.serializeLayoutToComment(preset.layout);
|
|
90
90
|
const title = params.title;
|
|
91
91
|
const subtitle = params.subtitle ? `
|
|
92
92
|
### ${params.subtitle}` : "";
|
|
@@ -227,7 +227,7 @@ Presenter Notes:
|
|
|
227
227
|
function executeApplySlideLayout(params) {
|
|
228
228
|
let layoutData = null;
|
|
229
229
|
if (params.presetId) {
|
|
230
|
-
const preset =
|
|
230
|
+
const preset = chunkJNTRKKJX_cjs.getSlideLayoutPresetById(params.presetId);
|
|
231
231
|
if (!preset) {
|
|
232
232
|
return {
|
|
233
233
|
success: false,
|
|
@@ -239,7 +239,7 @@ function executeApplySlideLayout(params) {
|
|
|
239
239
|
} else if (params.boxes && params.boxes.length > 0) {
|
|
240
240
|
layoutData = { boxes: params.boxes };
|
|
241
241
|
}
|
|
242
|
-
const updatedMarkdown =
|
|
242
|
+
const updatedMarkdown = chunkJNTRKKJX_cjs.updateSlideLayoutInMarkdown(
|
|
243
243
|
params.markdown,
|
|
244
244
|
params.slideIndex,
|
|
245
245
|
layoutData
|
|
@@ -250,7 +250,7 @@ function executeApplySlideLayout(params) {
|
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
252
|
function executeUpdatePresenterNotes(params) {
|
|
253
|
-
const { frontmatter, slides } =
|
|
253
|
+
const { frontmatter, slides } = chunkJNTRKKJX_cjs.splitMarkdownSlides(params.markdown);
|
|
254
254
|
if (params.slideIndex < 0 || params.slideIndex >= slides.length) {
|
|
255
255
|
return {
|
|
256
256
|
success: false,
|
|
@@ -469,22 +469,23 @@ function validateHtmlSlideDeck(deck, strict = false) {
|
|
|
469
469
|
slides.forEach((slide, idx) => {
|
|
470
470
|
const slideNumber = idx + 1;
|
|
471
471
|
const layoutId = slide.layoutId;
|
|
472
|
-
const preset =
|
|
472
|
+
const preset = chunkJNTRKKJX_cjs.HTML_SLIDE_PRESETS[layoutId];
|
|
473
473
|
if (!preset) {
|
|
474
474
|
issues.push({
|
|
475
475
|
slideIndex: slideNumber,
|
|
476
476
|
severity: "error",
|
|
477
477
|
rule: "INVALID_LAYOUT_PRESET",
|
|
478
|
-
message: `Unknown layoutId "${slide.layoutId}". Available presets: ${Object.keys(
|
|
478
|
+
message: `Unknown layoutId "${slide.layoutId}". Available presets: ${Object.keys(chunkJNTRKKJX_cjs.HTML_SLIDE_PRESETS).join(", ")}`
|
|
479
479
|
});
|
|
480
480
|
return;
|
|
481
481
|
}
|
|
482
482
|
if (preset.category === "cover" && idx === 0) hasCover = true;
|
|
483
483
|
if (preset.id === "checkpoint-quiz") hasQuiz = true;
|
|
484
484
|
if (preset.id === "summary-takeaways") hasSummary = true;
|
|
485
|
+
const slots = chunkJNTRKKJX_cjs.normalizeSlideSlots(slide);
|
|
485
486
|
for (const slotDef of preset.slots) {
|
|
486
487
|
if (slotDef.required) {
|
|
487
|
-
const val =
|
|
488
|
+
const val = slots[slotDef.name];
|
|
488
489
|
if (val === void 0 || val === null || typeof val === "string" && val.trim() === "") {
|
|
489
490
|
issues.push({
|
|
490
491
|
slideIndex: slideNumber,
|
|
@@ -495,7 +496,6 @@ function validateHtmlSlideDeck(deck, strict = false) {
|
|
|
495
496
|
}
|
|
496
497
|
}
|
|
497
498
|
}
|
|
498
|
-
const slots = slide.slots || {};
|
|
499
499
|
for (const [key, val] of Object.entries(slots)) {
|
|
500
500
|
if (typeof val === "string") {
|
|
501
501
|
const words = countWords(val);
|
|
@@ -624,7 +624,7 @@ function validateMarkdownSlideDeck(markdown, strict = false) {
|
|
|
624
624
|
suggestions: ['Provide Markdown slide content delimited by "---".']
|
|
625
625
|
};
|
|
626
626
|
}
|
|
627
|
-
const { slides: rawSlides } =
|
|
627
|
+
const { slides: rawSlides } = chunkJNTRKKJX_cjs.splitMarkdownSlides(markdown);
|
|
628
628
|
const activeSlides = rawSlides.filter((s) => s.trim().length > 0);
|
|
629
629
|
const slideCount = activeSlides.length;
|
|
630
630
|
if (slideCount === 0) {
|
|
@@ -867,12 +867,141 @@ Talk Track: Here we contrast synchronous blocking I/O with asynchronous event-dr
|
|
|
867
867
|
Cold-Call: "Jordan, looking at the left column, what happens to thread pool throughput when network latency quadruples?"
|
|
868
868
|
Scaffolding Tip: Compare it to ordering coffee at a counter (async buzzer) versus waiting at the register until the cup is brewed (sync blocking).
|
|
869
869
|
\`\`\`
|
|
870
|
+
|
|
871
|
+
## \u{1F9F1} MANDATORY JSON DECK OUTPUT STRUCTURE & SCHEMA:
|
|
872
|
+
You MUST output a single valid JSON object.
|
|
873
|
+
CRITICAL: All layout data MUST be placed inside the \`slots\` object of each slide. Never put raw unstructured strings like \`content: "..."\`!
|
|
874
|
+
|
|
875
|
+
\`\`\`json
|
|
876
|
+
{
|
|
877
|
+
"title": "Full Lesson Presentation Title",
|
|
878
|
+
"theme": "blue-professional",
|
|
879
|
+
"slides": [
|
|
880
|
+
{
|
|
881
|
+
"id": 1,
|
|
882
|
+
"layoutId": "hero-cover",
|
|
883
|
+
"slots": {
|
|
884
|
+
"tag": "Unit 01 \xB7 Lesson 01",
|
|
885
|
+
"title": "macOS & Xcode Environment Setup",
|
|
886
|
+
"subtitle": "Master the Apple developer toolchain and build your first SwiftUI application lifecycle",
|
|
887
|
+
"author": "Curriculum OS",
|
|
888
|
+
"date": "2026"
|
|
889
|
+
},
|
|
890
|
+
"notes": "Talk Track: Welcome everyone. Today we establish our core iOS development environment...\\nCold-Call: 'Alex, why do we need Xcode Command Line Tools?'\\nScaffolding Tip: Think of Xcode as the full workshop and the SDK as the raw materials."
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
"id": 2,
|
|
894
|
+
"layoutId": "split-concept-code",
|
|
895
|
+
"slots": {
|
|
896
|
+
"tag": "Architecture & Syntax",
|
|
897
|
+
"title": "SwiftUI App Entry Point",
|
|
898
|
+
"points": [
|
|
899
|
+
"@main attribute designates the entry point of the app",
|
|
900
|
+
"App protocol defines the structure and scene hierarchy",
|
|
901
|
+
"WindowGroup manages the root view lifecycle across platforms"
|
|
902
|
+
],
|
|
903
|
+
"code": "import SwiftUI\\n\\n@main\\nstruct MyApp: App {\\n var body: some Scene {\\n WindowGroup {\\n ContentView()\\n }\\n }\\n}",
|
|
904
|
+
"language": "swift",
|
|
905
|
+
"codeNote": "Notice how Scene encapsulates WindowGroup automatically"
|
|
906
|
+
},
|
|
907
|
+
"notes": "Talk Track: ...\\nCold-Call: ...\\nScaffolding Tip: ..."
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
"id": 3,
|
|
911
|
+
"layoutId": "three-cards-grid",
|
|
912
|
+
"slots": {
|
|
913
|
+
"tag": "Core Pillars",
|
|
914
|
+
"title": "Three Pillars of App State",
|
|
915
|
+
"cards": [
|
|
916
|
+
{ "badge": "01", "title": "Active State", "desc": "App is in foreground and responding to user events directly." },
|
|
917
|
+
{ "badge": "02", "title": "Inactive State", "desc": "App is transitioning, interrupted by system dialogs or Control Center." },
|
|
918
|
+
{ "badge": "03", "title": "Background State", "desc": "Executing background tasks or preparing for memory suspension." }
|
|
919
|
+
]
|
|
920
|
+
},
|
|
921
|
+
"notes": "Talk Track: ...\\nCold-Call: ...\\nScaffolding Tip: ..."
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
"id": 4,
|
|
925
|
+
"layoutId": "timeline-steps",
|
|
926
|
+
"slots": {
|
|
927
|
+
"tag": "Step-by-Step",
|
|
928
|
+
"title": "Xcode Setup Workflow",
|
|
929
|
+
"steps": [
|
|
930
|
+
{ "stepNum": 1, "title": "Download Xcode", "desc": "Install latest Xcode from the Mac App Store" },
|
|
931
|
+
{ "stepNum": 2, "title": "Command Line Tools", "desc": "Run xcode-select --install in Terminal" },
|
|
932
|
+
{ "stepNum": 3, "title": "Select Simulators", "desc": "Download iOS 18+ runtime simulators" },
|
|
933
|
+
{ "stepNum": 4, "title": "Verify Build", "desc": "Create a new SwiftUI project and press Cmd+R" }
|
|
934
|
+
]
|
|
935
|
+
},
|
|
936
|
+
"notes": "Talk Track: ...\\nCold-Call: ...\\nScaffolding Tip: ..."
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
"id": 5,
|
|
940
|
+
"layoutId": "two-columns-compare",
|
|
941
|
+
"slots": {
|
|
942
|
+
"tag": "Comparison",
|
|
943
|
+
"title": "SwiftUI vs UIKit Architecture",
|
|
944
|
+
"col1Title": "SwiftUI (Declarative)",
|
|
945
|
+
"col1Items": [
|
|
946
|
+
"State drives the UI automatically",
|
|
947
|
+
"Lightweight immutable structs",
|
|
948
|
+
"Cross-platform unified API"
|
|
949
|
+
],
|
|
950
|
+
"col2Title": "UIKit (Imperative)",
|
|
951
|
+
"col2Items": [
|
|
952
|
+
"Manual view controller manipulation",
|
|
953
|
+
"Heavyweight class hierarchies",
|
|
954
|
+
"Explicit event-driven updates"
|
|
955
|
+
]
|
|
956
|
+
},
|
|
957
|
+
"notes": "Talk Track: ...\\nCold-Call: ...\\nScaffolding Tip: ..."
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
"id": 6,
|
|
961
|
+
"layoutId": "checkpoint-quiz",
|
|
962
|
+
"slots": {
|
|
963
|
+
"tag": "Knowledge Check",
|
|
964
|
+
"question": "Which SwiftUI modifier is used to observe external observable state objects?",
|
|
965
|
+
"options": [
|
|
966
|
+
{ "label": "A", "text": "@State" },
|
|
967
|
+
{ "label": "B", "text": "@StateObject / @ObservedObject" },
|
|
968
|
+
{ "label": "C", "text": "@Binding" },
|
|
969
|
+
{ "label": "D", "text": "@Environment" }
|
|
970
|
+
],
|
|
971
|
+
"explanation": "@StateObject manages the lifecycle of reference-type ObservableObjects, while @State is for value types."
|
|
972
|
+
},
|
|
973
|
+
"notes": "Talk Track: ...\\nCold-Call: ...\\nScaffolding Tip: ..."
|
|
974
|
+
},
|
|
975
|
+
{
|
|
976
|
+
"id": 7,
|
|
977
|
+
"layoutId": "summary-takeaways",
|
|
978
|
+
"slots": {
|
|
979
|
+
"tag": "Recap & Next",
|
|
980
|
+
"title": "Lesson Summary & Key Takeaways",
|
|
981
|
+
"takeaways": [
|
|
982
|
+
"Configured complete developer toolchain with Xcode 16+",
|
|
983
|
+
"Understood SwiftUI declarative lifecycle and @main entry point",
|
|
984
|
+
"Mastered App State transitions between active, inactive, and background"
|
|
985
|
+
],
|
|
986
|
+
"nextStep": "Lesson 02: State Management & Reactive Data Flow with @State and @Binding"
|
|
987
|
+
},
|
|
988
|
+
"notes": "Talk Track: ...\\nCold-Call: ...\\nScaffolding Tip: ..."
|
|
989
|
+
}
|
|
990
|
+
]
|
|
991
|
+
}
|
|
992
|
+
\`\`\`
|
|
993
|
+
|
|
994
|
+
## \u{1F6AB} STRICT ANTI-SLOP CONSTRAINTS:
|
|
995
|
+
1. NEVER output a raw unstructured string like \`content: "..."\` or \`content: "Concept: ... Code snippet: ..."\`. All slide content MUST be placed inside the \`slots\` object with its specific keys (\`points\`, \`code\`, \`cards\`, \`steps\`, \`options\`, \`takeaways\`).
|
|
996
|
+
2. NEVER use ellipsis \`...\` or placeholder comments in \`code\`. Every code snippet MUST be real, fully typed, syntax-valid, and pedagogical.
|
|
997
|
+
3. NEVER leave \`slots\` empty \`{}\`.
|
|
998
|
+
4. Output 6 to 8 substantive, rich slides covering the lesson plan thoroughly.
|
|
870
999
|
`;
|
|
871
1000
|
|
|
872
1001
|
// src/ai/html/tools.ts
|
|
873
1002
|
function handleListHtmlSlidePresets(input) {
|
|
874
1003
|
const category = input.category || "all";
|
|
875
|
-
const presets = Object.values(
|
|
1004
|
+
const presets = Object.values(chunkJNTRKKJX_cjs.HTML_SLIDE_PRESETS).filter((p) => category === "all" || p.category === category).map((p) => ({
|
|
876
1005
|
id: p.id,
|
|
877
1006
|
name: p.name,
|
|
878
1007
|
category: p.category,
|
|
@@ -888,12 +1017,12 @@ function handleListHtmlSlidePresets(input) {
|
|
|
888
1017
|
return {
|
|
889
1018
|
success: true,
|
|
890
1019
|
presets,
|
|
891
|
-
availableThemes: Object.keys(
|
|
1020
|
+
availableThemes: Object.keys(chunkJNTRKKJX_cjs.HTML_THEMES)
|
|
892
1021
|
};
|
|
893
1022
|
}
|
|
894
1023
|
function handleGenerateHtmlDeck(input) {
|
|
895
1024
|
try {
|
|
896
|
-
const result =
|
|
1025
|
+
const result = chunkJNTRKKJX_cjs.compileHtmlDeck(input);
|
|
897
1026
|
return {
|
|
898
1027
|
success: true,
|
|
899
1028
|
title: result.title,
|
|
@@ -909,7 +1038,7 @@ function handleGenerateHtmlDeck(input) {
|
|
|
909
1038
|
}
|
|
910
1039
|
}
|
|
911
1040
|
function handleCreateHtmlSlide(input) {
|
|
912
|
-
const preset =
|
|
1041
|
+
const preset = chunkJNTRKKJX_cjs.HTML_SLIDE_PRESETS[input.layoutId];
|
|
913
1042
|
if (!preset) {
|
|
914
1043
|
return {
|
|
915
1044
|
success: false,
|