@thanh01.pmt/presentation-kit 0.2.2 → 0.2.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkOEAOYF7C_cjs = require('../chunk-OEAOYF7C.cjs');
3
+ var chunkO5MCKVEA_cjs = require('../chunk-O5MCKVEA.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" ? chunkOEAOYF7C_cjs.SLIDE_LAYOUT_PRESETS : chunkOEAOYF7C_cjs.getSlideLayoutPresetsByCategory(category);
67
+ const presets = !category || category === "all" ? chunkO5MCKVEA_cjs.SLIDE_LAYOUT_PRESETS : chunkO5MCKVEA_cjs.getSlideLayoutPresetsByCategory(category);
68
68
  return {
69
69
  count: presets.length,
70
70
  presets: presets.map((p) => ({
@@ -78,15 +78,15 @@ function executeListSlidePresets(params) {
78
78
  };
79
79
  }
80
80
  function executeCreateSlideFromPreset(params) {
81
- const preset = chunkOEAOYF7C_cjs.getSlideLayoutPresetById(params.presetId);
81
+ const preset = chunkO5MCKVEA_cjs.getSlideLayoutPresetById(params.presetId);
82
82
  if (!preset) {
83
83
  return {
84
84
  success: false,
85
85
  slideMarkdown: "",
86
- error: `Kh\xF4ng t\xECm th\u1EA5y preset v\u1EDBi ID: "${params.presetId}". S\u1EED d\u1EE5ng listSlidePresets \u0111\u1EC3 xem c\xE1c m\u1EABu c\xF3 s\u1EB5n.`
86
+ error: `Preset with ID "${params.presetId}" not found. Use listSlidePresets to see available layout templates.`
87
87
  };
88
88
  }
89
- const layoutComment = chunkOEAOYF7C_cjs.serializeLayoutToComment(preset.layout);
89
+ const layoutComment = chunkO5MCKVEA_cjs.serializeLayoutToComment(preset.layout);
90
90
  const title = params.title;
91
91
  const subtitle = params.subtitle ? `
92
92
  ### ${params.subtitle}` : "";
@@ -97,20 +97,20 @@ function executeCreateSlideFromPreset(params) {
97
97
  case "title-hero":
98
98
  body = `${subtitle}
99
99
 
100
- **Ng\u01B0\u1EDDi tr\xECnh b\xE0y:** ${c.speaker || "Gi\u1EA3ng vi\xEAn"} | **Th\u1EDDi l\u01B0\u1EE3ng:** ${c.duration || "45 ph\xFAt"} | **Ch\u1EE7 \u0111\u1EC1:** ${c.topic || title}`;
100
+ **Presenter:** ${c.speaker || "Lead Instructor"} | **Duration:** ${c.duration || "45 mins"} | **Topic:** ${c.topic || title}`;
101
101
  break;
102
102
  case "two-column-split":
103
103
  body = `<div class="columns-2">
104
104
  <div>
105
105
 
106
- ### ${c.leftHeader || "C\xE1ch ti\u1EBFp c\u1EADn A"}
107
- ${c.leftCol || "- \u0110i\u1EC3m 1\n- \u0110i\u1EC3m 2\n- \u0110i\u1EC3m 3"}
106
+ ### ${c.leftHeader || "Approach A"}
107
+ ${c.leftCol || "- Point 1\n- Point 2\n- Point 3"}
108
108
 
109
109
  </div>
110
110
  <div>
111
111
 
112
- ### ${c.rightHeader || "C\xE1ch ti\u1EBFp c\u1EADn B"}
113
- ${c.rightCol || "- \u0110i\u1EC3m 1\n- \u0110i\u1EC3m 2\n- \u0110i\u1EC3m 3"}
112
+ ### ${c.rightHeader || "Approach B"}
113
+ ${c.rightCol || "- Point 1\n- Point 2\n- Point 3"}
114
114
 
115
115
  </div>
116
116
  </div>`;
@@ -120,14 +120,14 @@ ${c.rightCol || "- \u0110i\u1EC3m 1\n- \u0110i\u1EC3m 2\n- \u0110i\u1EC3m 3"}
120
120
  <div>
121
121
 
122
122
  \`\`\`${c.lang || "ts"}
123
- ${c.code || "// Code snippet \u1EDF \u0111\xE2y\nconst example = true;"}
123
+ ${c.code || "// Core implementation logic\nconst isValid = true;"}
124
124
  \`\`\`
125
125
 
126
126
  </div>
127
127
  <div>
128
128
 
129
- ### \u{1F50D} \u0110i\u1EC3m c\u1ED1t l\xF5i:
130
- ${c.notes || "1. **Ph\xE2n t\xEDch d\xF2ng 1:** Kh\u1EDFi t\u1EA1o\n2. **Ph\xE2n t\xEDch d\xF2ng 2:** Th\u1EF1c thi\n3. **L\u01B0u \xFD:** \u0110i\u1EC1u ki\u1EC7n bi\xEAn"}
129
+ ### \u{1F50D} Key Invariants:
130
+ ${c.notes || "1. **Validation:** Checks payload before processing\n2. **Execution:** Enforces deterministic state\n3. **Resilience:** Handles edge case errors"}
131
131
 
132
132
  </div>
133
133
  </div>`;
@@ -137,64 +137,64 @@ ${c.notes || "1. **Ph\xE2n t\xEDch d\xF2ng 1:** Kh\u1EDFi t\u1EA1o\n2. **Ph\xE2n
137
137
  <div>
138
138
 
139
139
  # ${c.metric1Val || "99.9%"}
140
- ### ${c.metric1Title || "Ch\u1EC9 s\u1ED1 1"}
141
- ${c.metric1Desc || "M\xF4 t\u1EA3 ng\u1EAFn g\u1ECDn v\u1EC1 ch\u1EC9 s\u1ED1."}
140
+ ### ${c.metric1Title || "Availability"}
141
+ ${c.metric1Desc || "Automated multi-region failover routing."}
142
142
 
143
143
  </div>
144
144
  <div>
145
145
 
146
146
  # ${c.metric2Val || "10x"}
147
- ### ${c.metric2Title || "Ch\u1EC9 s\u1ED1 2"}
148
- ${c.metric2Desc || "M\xF4 t\u1EA3 ng\u1EAFn g\u1ECDn v\u1EC1 ch\u1EC9 s\u1ED1."}
147
+ ### ${c.metric2Title || "Throughput"}
148
+ ${c.metric2Desc || "Sub-millisecond processing latency."}
149
149
 
150
150
  </div>
151
151
  <div>
152
152
 
153
153
  # ${c.metric3Val || "0"}
154
- ### ${c.metric3Title || "Ch\u1EC9 s\u1ED1 3"}
155
- ${c.metric3Desc || "M\xF4 t\u1EA3 ng\u1EAFn g\u1ECDn v\u1EC1 ch\u1EC9 s\u1ED1."}
154
+ ### ${c.metric3Title || "Breaches"}
155
+ ${c.metric3Desc || "Continuous SOC2 compliance auditing."}
156
156
 
157
157
  </div>
158
158
  </div>`;
159
159
  break;
160
160
  case "process-flow":
161
161
  body = `\`\`\`mermaid
162
- ${c.mermaid || "graph LR\n A[B\u01B0\u1EDBc 1] --> B[B\u01B0\u1EDBc 2]\n B --> C[B\u01B0\u1EDBc 3]\n C --> D[Ho\xE0n th\xE0nh]"}
162
+ ${c.mermaid || "graph LR\n A[1. Ingress] --> B[2. Gateway]\n B --> C[3. Service]\n C --> D[4. Storage]"}
163
163
  \`\`\`
164
164
 
165
- ${c.summary || "- **Giai \u0111o\u1EA1n 1:** Kh\u1EDFi \u0111\u1ED9ng\n- **Giai \u0111o\u1EA1n 2:** X\u1EED l\xFD d\u1EEF li\u1EC7u\n- **Giai \u0111o\u1EA1n 3:** K\u1EBFt xu\u1EA5t k\u1EBFt qu\u1EA3"}`;
165
+ ${c.summary || "- **Phase 1 & 2:** Client connection and load balancing.\n- **Phase 3 & 4:** Business logic execution and data commit."}`;
166
166
  break;
167
167
  case "quote-highlight":
168
- body = `> "${c.quote || "S\u1EF1 \u0111\u01A1n gi\u1EA3n l\xE0 ch\xECa kh\xF3a c\u1EE7a \u0111\u1ED9 tin c\u1EADy."}"
168
+ body = `> "${c.quote || "Simplicity is prerequisite for reliability."}"
169
169
  >
170
- > \u2014 **${c.author || "Danh ng\xF4n c\xF4ng ngh\u1EC7"}**`;
170
+ > \u2014 **${c.author || "Architecture Principle"}**`;
171
171
  break;
172
172
  case "quiz-checkpoint":
173
- body = `> **C\xE2u h\u1ECFi:** ${c.question || "Ph\u01B0\u01A1ng \xE1n n\xE0o sau \u0111\xE2y l\xE0 t\u1ED1i \u01B0u nh\u1EA5t?"}
173
+ body = `> **Question:** ${c.question || "Which architecture pattern best ensures reliable message delivery?"}
174
174
 
175
- - **A.** ${c.optA || "L\u1EF1a ch\u1ECDn A"}
176
- - **B.** ${c.optB || "L\u1EF1a ch\u1ECDn B (Ch\xEDnh x\xE1c)"}
177
- - **C.** ${c.optC || "L\u1EF1a ch\u1ECDn C"}
178
- - **D.** ${c.optD || "L\u1EF1a ch\u1ECDn D"}`;
175
+ - **A.** ${c.optA || "Direct synchronous HTTP request with short timeout"}
176
+ - **B.** ${c.optB || "Persistent Message Queue with Dead-Letter Queue (Correct)"}
177
+ - **C.** ${c.optC || "In-memory client cache without persistence"}
178
+ - **D.** ${c.optD || "Silently dropping failed packets"}`;
179
179
  break;
180
180
  case "tiered-practice-3cards":
181
181
  body = `<div class="columns-3">
182
182
  <div>
183
183
 
184
- ### \u{1F949} H\u1EA1ng \u0110\u1ED3ng (Bronze)
185
- ${c.bronze || "- B\xE0i t\u1EADp c\u01A1 b\u1EA3n\n- 1 test case m\u1EABu"}
184
+ ### \u{1F949} Bronze Tier
185
+ ${c.bronze || "- Implement baseline function\n- Pass 2 sample unit tests"}
186
186
 
187
187
  </div>
188
188
  <div>
189
189
 
190
- ### \u{1F948} H\u1EA1ng B\u1EA1c (Silver)
191
- ${c.silver || "- T\u1ED1i \u01B0u thu\u1EADt to\xE1n\n- X\u1EED l\xFD \u0111i\u1EC1u ki\u1EC7n bi\xEAn"}
190
+ ### \u{1F948} Silver Tier
191
+ ${c.silver || "- Add boundary error handling\n- Optimize algorithm complexity"}
192
192
 
193
193
  </div>
194
194
  <div>
195
195
 
196
- ### \u{1F947} H\u1EA1ng V\xE0ng (Gold)
197
- ${c.gold || "- T\xEDnh n\u0103ng m\u1EDF r\u1ED9ng\n- T\u1EF1 \u0111\u1ED9ng h\xF3a unit test"}
196
+ ### \u{1F947} Gold Tier
197
+ ${c.gold || "- Design extension feature\n- Write automated integration tests"}
198
198
 
199
199
  </div>
200
200
  </div>`;
@@ -212,8 +212,8 @@ ${params.presenterNotes.map((n) => `- ${n}`).join("\n")}
212
212
 
213
213
  <!--
214
214
  Presenter Notes:
215
- - Gi\u1EA3i th\xEDch kh\xE1i ni\u1EC7m ch\xEDnh tr\xEAn slide.
216
- - \u0110\u1EB7t c\xE2u h\u1ECFi t\u01B0\u01A1ng t\xE1c cho c\u1EA3 l\u1EDBp.
215
+ - Explain the primary concept on this slide.
216
+ - Ask a diagnostic cold-call question to check comprehension.
217
217
  -->`;
218
218
  const slideMarkdown = `${layoutComment}
219
219
 
@@ -227,19 +227,19 @@ Presenter Notes:
227
227
  function executeApplySlideLayout(params) {
228
228
  let layoutData = null;
229
229
  if (params.presetId) {
230
- const preset = chunkOEAOYF7C_cjs.getSlideLayoutPresetById(params.presetId);
230
+ const preset = chunkO5MCKVEA_cjs.getSlideLayoutPresetById(params.presetId);
231
231
  if (!preset) {
232
232
  return {
233
233
  success: false,
234
234
  updatedMarkdown: params.markdown,
235
- error: `Kh\xF4ng t\xECm th\u1EA5y preset v\u1EDBi ID: "${params.presetId}"`
235
+ error: `Preset with ID "${params.presetId}" not found.`
236
236
  };
237
237
  }
238
238
  layoutData = preset.layout;
239
239
  } else if (params.boxes && params.boxes.length > 0) {
240
240
  layoutData = { boxes: params.boxes };
241
241
  }
242
- const updatedMarkdown = chunkOEAOYF7C_cjs.updateSlideLayoutInMarkdown(
242
+ const updatedMarkdown = chunkO5MCKVEA_cjs.updateSlideLayoutInMarkdown(
243
243
  params.markdown,
244
244
  params.slideIndex,
245
245
  layoutData
@@ -250,12 +250,12 @@ function executeApplySlideLayout(params) {
250
250
  };
251
251
  }
252
252
  function executeUpdatePresenterNotes(params) {
253
- const { frontmatter, slides } = chunkOEAOYF7C_cjs.splitMarkdownSlides(params.markdown);
253
+ const { frontmatter, slides } = chunkO5MCKVEA_cjs.splitMarkdownSlides(params.markdown);
254
254
  if (params.slideIndex < 0 || params.slideIndex >= slides.length) {
255
255
  return {
256
256
  success: false,
257
257
  updatedMarkdown: params.markdown,
258
- error: `Slide index ${params.slideIndex} ngo\xE0i ph\u1EA1m vi (t\u1ED5ng s\u1ED1 slides: ${slides.length})`
258
+ error: `Slide index ${params.slideIndex} out of bounds (total slides: ${slides.length})`
259
259
  };
260
260
  }
261
261
  let slideContent = slides[params.slideIndex];
@@ -305,21 +305,21 @@ function executeGenerateDeckOutline(params) {
305
305
  format: formatLabel,
306
306
  recommendedSlideCount: targetSlideCount,
307
307
  structureGuidelines: [
308
- "\xC1p d\u1EE5ng nguy\xEAn t\u1EAFc: M\u1ED9t \xFD t\u01B0\u1EDFng duy nh\u1EA5t tr\xEAn m\u1ED7i slide (One Idea Per Slide).",
309
- "Gi\u1EDBi h\u1EA1n t\u1EEB: T\u1ED1i \u0111a 40 t\u1EEB tr\xEAn m\u1ED7i card/c\u1ED9t \u0111\u1EC3 ch\u1ED1ng tr\xE0n ch\u1EEF (Zero Scroll Invariant).",
310
- "T\u1EF7 l\u1EC7 hi\u1EC3n th\u1ECB: Chu\u1EA9n 16:9 v\u1EDBi h\u1EC7 t\u1ECDa \u0111\u1ED9 1280x720.",
311
- "B\u1EAFt bu\u1ED9c c\xF3 kh\u1ED1i Presenter Notes ch\u1EE9a: Talk track gi\u1EA3ng vi\xEAn + 1 c\xE2u h\u1ECFi t\u01B0\u01A1ng t\xE1c cold-call."
308
+ 'Apply the "One Idea Per Slide" invariant.',
309
+ "Enforce Word Budget: Maximum 40 words per card or column (Zero-Scroll Invariant).",
310
+ "Target 16:9 aspect ratio in 1280x720 coordinate space.",
311
+ "Every slide must conclude with Presenter Notes: Teacher talk track + 1 diagnostic cold-call question."
312
312
  ],
313
313
  suggestedOutline: [
314
- { slide: 1, type: "title-hero", title: `\u{1F680} ${params.topic}`, intent: "G\xE2y \u1EA5n t\u01B0\u1EE3ng ban \u0111\u1EA7u v\xE0 gi\u1EDBi thi\u1EC7u di\u1EC5n gi\u1EA3" },
315
- { slide: 2, type: "agenda-timeline", title: "\u{1F5FA}\uFE0F L\u1ED9 tr\xECnh ho\u1EA1t \u0111\u1ED9ng", intent: "\u0110\u1ECBnh h\xECnh c\u1EA5u tr\xFAc th\u1EDDi gian v\xE0 k\u1EBFt qu\u1EA3 \u0111\u1EA7u ra" },
316
- { slide: 3, type: "two-column-split", title: "\u26A1 B\u1ED1i c\u1EA3nh & Th\u1EED th\xE1ch", intent: "So s\xE1nh c\xE1ch l\xE0m c\u0169 vs v\u1EA5n \u0111\u1EC1 th\u1EF1c t\u1EBF" },
317
- { slide: 4, type: "process-flow", title: "\u{1F504} Ki\u1EBFn tr\xFAc c\u1ED1t l\xF5i", intent: "S\u01A1 \u0111\u1ED3 lu\u1ED3ng x\u1EED l\xFD t\u1ED5ng quan" },
318
- { slide: 5, type: "code-explainer", title: "\u{1F4BB} Ph\xE2n t\xEDch m\xE3 ngu\u1ED3n", intent: "\u0110i s\xE2u v\xE0o implementation k\u1EF9 thu\u1EADt" },
319
- { slide: 6, type: "metrics-3-card", title: "\u{1F4CA} 3 Ch\u1EC9 s\u1ED1 \u0111o l\u01B0\u1EDDng", intent: "\u0110\u1ECBnh l\u01B0\u1EE3ng hi\u1EC7u n\u0103ng v\xE0 t\xEDnh hi\u1EC7u qu\u1EA3" },
320
- { slide: 7, type: "tiered-practice-3cards", title: "\u{1F6E0}\uFE0F Th\u1EED th\xE1ch ph\xE2n h\xF3a", intent: "Th\u1EF1c h\xE0nh t\u1EA1i ch\u1ED7 theo 3 b\u1EADc Bronze-Silver-Gold" },
321
- { slide: 8, type: "quiz-checkpoint", title: "\u{1F3AF} Ki\u1EC3m tra nhanh", intent: "\u0110\xE1nh gi\xE1 m\u1EE9c \u0111\u1ED9 ti\u1EBFp thu (Formative Checkpoint)" },
322
- { slide: 9, type: "takeaways-summary", title: "\u{1F3C1} T\u1ED5ng k\u1EBFt c\u1ED1t l\xF5i", intent: "3 b\xE0i h\u1ECDc r\xFAt ra v\xE0 nhi\u1EC7m v\u1EE5 ti\u1EBFp theo" }
314
+ { slide: 1, type: "title-hero", title: `\u{1F680} ${params.topic}`, intent: "Opening hook and speaker credentialing" },
315
+ { slide: 2, type: "agenda-timeline", title: "\u{1F5FA}\uFE0F Session Milestones", intent: "Set time budget expectations and learning deliverables" },
316
+ { slide: 3, type: "two-column-split", title: "\u26A1 Problem vs Opportunity", intent: "Contrast legacy bottlenecks against the modern solution" },
317
+ { slide: 4, type: "process-flow", title: "\u{1F504} Architectural Flow", intent: "High-level system topology and sequence diagram" },
318
+ { slide: 5, type: "code-explainer", title: "\u{1F4BB} Core Code Walkthrough", intent: "Deep-dive into production implementation logic" },
319
+ { slide: 6, type: "metrics-3-card", title: "\u{1F4CA} Benchmark Results", intent: "Quantify performance and reliability gains" },
320
+ { slide: 7, type: "tiered-practice-3cards", title: "\u{1F6E0}\uFE0F Hands-On Challenge", intent: "Differentiated practice across Bronze, Silver, and Gold tiers" },
321
+ { slide: 8, type: "quiz-checkpoint", title: "\u{1F3AF} Formative Checkpoint", intent: "Real-time diagnostic voting to verify mastery" },
322
+ { slide: 9, type: "takeaways-summary", title: "\u{1F3C1} Key Takeaways", intent: "Synthesis of 3 core lessons and next action items" }
323
323
  ].slice(0, Math.max(5, Math.min(targetSlideCount, 10)))
324
324
  };
325
325
  }
@@ -352,7 +352,7 @@ Structure decks based on allocated talk time (averaging 1.5 - 2 minutes per slid
352
352
  ## 3. STRICT WORD BUDGET (ZERO-SCROLL INVARIANT)
353
353
  - **Hard Limit:** Maximum **35 - 40 words** per card or column.
354
354
  - Never write paragraphs longer than 2 sentences. Use structured bullets with bold anchor terms:
355
- - Format: \`- **Kh\xE1i ni\u1EC7m then ch\u1ED1t:** M\xF4 t\u1EA3 s\xFAc t\xEDch trong 1 d\xF2ng.\`
355
+ - Format: \`- **Key Concept:** Concise explanation in a single line.\`
356
356
  - Vertical scrolling inside a slide is STRICTLY FORBIDDEN. Content must fit the 16:9 (1280x720) canvas cleanly.
357
357
 
358
358
  ---
@@ -362,12 +362,14 @@ Structure decks based on allocated talk time (averaging 1.5 - 2 minutes per slid
362
362
  \`\`\`html
363
363
  <div class="columns-2">
364
364
  <div>
365
- ### \u{1F534} C\u0169 / Th\xE1ch Th\u1EE9c
366
- - ...
365
+ ### \u{1F534} Legacy / Challenge
366
+ - High idle compute overhead
367
+ - Cascading timeout failures
367
368
  </div>
368
369
  <div>
369
- ### \u{1F7E2} M\u1EDBi / Gi\u1EA3i Ph\xE1p
370
- - ...
370
+ ### \u{1F7E2} Modern / Solution
371
+ - Event-driven webhook streams
372
+ - Automatic queue backpressure
371
373
  </div>
372
374
  </div>
373
375
  \`\`\`
@@ -378,16 +380,16 @@ Structure decks based on allocated talk time (averaging 1.5 - 2 minutes per slid
378
380
  ## 5. MANDATORY PRESENTER NOTES (TEACHER TALK TRACK)
379
381
  Every single slide MUST conclude with an HTML comment block containing:
380
382
  1. **Talk Track:** 2-3 sentences of what the speaker should say out loud.
381
- 2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student.
382
- 3. **Scaffolding Tip:** 1 hint if students look confused.
383
+ 2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student or attendee.
384
+ 3. **Scaffolding Tip:** 1 hint or real-world analogy if learners look confused.
383
385
 
384
386
  Example:
385
387
  \`\`\`markdown
386
388
  <!--
387
389
  Presenter Notes:
388
- - Tr\xECnh b\xE0y \u0111i\u1EC3m ngh\u1EBDn l\u1EDBn nh\u1EA5t trong vi\u1EC7c m\u1EDF r\u1ED9ng quy m\xF4 d\u1EEF li\u1EC7u.
389
- - Cold-call: "Em Nguy\u1EC5n V\u0103n B, n\u1EBFu s\u1ED1 l\u01B0\u1EE3ng request t\u0103ng g\u1EA5p 10 l\u1EA7n th\xEC \u0111i\u1EC3m n\xE0o s\u1EBD s\u1EADp \u0111\u1EA7u ti\xEAn?"
390
- - G\u1EE3i \xFD g\u1EE3i m\u1EDF: Nh\u1EAFc h\u1ECDc vi\xEAn nh\u1EDB l\u1EA1i kh\xE1i ni\u1EC7m I/O bottleneck \u1EDF b\xE0i tr\u01B0\u1EDBc.
390
+ - Walk through the primary bottleneck when scaling database writes under high concurrency.
391
+ - Cold-call: "Alex, if traffic spikes 10x in 1 minute, which subsystem will experience lock contention first?"
392
+ - Scaffolding tip: Remind the room of the I/O saturation trade-off discussed in the previous module.
391
393
  -->
392
394
  \`\`\`
393
395
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ai/schemas.ts","../../src/ai/tools.ts","../../src/ai/prompt.ts"],"names":["z","SLIDE_LAYOUT_PRESETS","getSlideLayoutPresetsByCategory","getSlideLayoutPresetById","serializeLayoutToComment","updateSlideLayoutInMarkdown","splitMarkdownSlides"],"mappings":"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","file":"index.cjs","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// @learnwell/presentation-kit — AI Tool Schemas (Zod)\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport { z } from 'zod';\n\nexport const listSlidePresetsSchema = z.object({\n category: z.enum([\n 'all',\n 'cover',\n 'content',\n 'split',\n 'code',\n 'metrics',\n 'diagram',\n 'quote',\n 'assessment',\n ]).optional().describe('Optional category filter for layout presets'),\n});\n\nexport const createSlideFromPresetSchema = z.object({\n presetId: z.string().describe(\n 'ID of the layout preset: title-hero, two-column-split, code-explainer, metrics-3-card, process-flow, quote-highlight, quiz-checkpoint, tiered-practice-3cards, agenda-timeline, takeaways-summary'\n ),\n title: z.string().describe('Slide heading or title'),\n subtitle: z.string().optional().describe('Optional subtitle or section context'),\n content: z.record(z.string()).optional().describe(\n 'Key-value pairs for preset sections. For two-column-split: leftCol, rightCol. For code-explainer: code, language, notes. For metrics-3-card: card1Title, card1Val, card1Desc, etc.'\n ),\n customMarkdownBody: z.string().optional().describe(\n 'Raw markdown body to place inside the layout container (overrides content key-value pairs if provided)'\n ),\n presenterNotes: z.array(z.string()).optional().describe(\n 'Teacher talk track, cold-call check questions, or scaffolding notes for this slide'\n ),\n});\n\nexport const applySlideLayoutSchema = z.object({\n markdown: z.string().describe('Full Markdown slide deck content'),\n slideIndex: z.number().int().min(0).describe('0-based index of the target slide to modify'),\n presetId: z.string().optional().describe('Optional preset ID to apply to this slide'),\n boxes: z.array(\n z.object({\n id: z.string(),\n target: z.string().optional(),\n pos: z.tuple([z.number(), z.number(), z.number(), z.number()]).describe('[x, y, width, height] in 1280x720 canvas coordinates'),\n fontSize: z.string().optional(),\n color: z.string().optional(),\n textAlign: z.enum(['left', 'center', 'right', 'justify']).optional(),\n style: z.string().optional(),\n })\n ).optional().describe('Custom boxes if not using presetId'),\n});\n\nexport const updatePresenterNotesSchema = z.object({\n markdown: z.string().describe('Full Markdown slide deck content'),\n slideIndex: z.number().int().min(0).describe('0-based index of the target slide'),\n notes: z.array(z.string()).describe('List of speaker notes / talk tracks to set for this slide'),\n});\n\nexport const generateDeckOutlineSchema = z.object({\n topic: z.string().describe('Main subject or topic of the presentation'),\n durationMins: z.number().int().min(3).max(120).default(15).describe('Estimated duration in minutes (5m: 5-7 slides, 15m: 12-18 slides, 30m: 25-35 slides)'),\n audience: z.string().describe('Target audience profile (e.g. Grade 10 students, junior developers, enterprise clients)'),\n keyObjectives: z.array(z.string()).describe('2-4 key learning or decision objectives'),\n techStack: z.string().optional().describe('Optional programming language, framework, or hardware kit'),\n});\n","// ═══════════════════════════════════════════════════════════════════════════════\n// @learnwell/presentation-kit — AI Tool Handlers\n// Pure execution handlers for Vercel AI SDK / OpenAI tool calls\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport {\n SLIDE_LAYOUT_PRESETS,\n getSlideLayoutPresetById,\n getSlideLayoutPresetsByCategory,\n type SlideLayoutCategory,\n} from '../core/layout/presets.js';\nimport {\n updateSlideLayoutInMarkdown,\n splitMarkdownSlides,\n serializeLayoutToComment,\n} from '../core/layout/serializer.js';\nimport type { SlideLayoutData } from '../types.js';\n\n/**\n * Execute: listSlidePresets\n */\nexport function executeListSlidePresets(params?: { category?: string }) {\n const category = params?.category;\n const presets = (!category || category === 'all')\n ? SLIDE_LAYOUT_PRESETS\n : getSlideLayoutPresetsByCategory(category as SlideLayoutCategory);\n\n return {\n count: presets.length,\n presets: presets.map(p => ({\n id: p.id,\n name: p.name,\n category: p.category,\n description: p.description,\n boxCount: p.layout.boxes.length,\n snippetPreview: p.markdownSnippet.split('\\n').slice(0, 8).join('\\n') + '\\n...',\n })),\n };\n}\n\n/**\n * Execute: createSlideFromPreset\n */\nexport function executeCreateSlideFromPreset(params: {\n presetId: string;\n title: string;\n subtitle?: string;\n content?: Record<string, string>;\n customMarkdownBody?: string;\n presenterNotes?: string[];\n}): { success: boolean; slideMarkdown: string; presetName?: string; error?: string } {\n const preset = getSlideLayoutPresetById(params.presetId);\n if (!preset) {\n return {\n success: false,\n slideMarkdown: '',\n error: `Không tìm thấy preset với ID: \"${params.presetId}\". Sử dụng listSlidePresets để xem các mẫu có sẵn.`,\n };\n }\n\n const layoutComment = serializeLayoutToComment(preset.layout);\n const title = params.title;\n const subtitle = params.subtitle ? `\\n### ${params.subtitle}` : '';\n\n let body = params.customMarkdownBody;\n\n if (!body) {\n const c = params.content || {};\n switch (preset.id) {\n case 'title-hero':\n body = `${subtitle}\\n\\n**Người trình bày:** ${c.speaker || 'Giảng viên'} | **Thời lượng:** ${c.duration || '45 phút'} | **Chủ đề:** ${c.topic || title}`;\n break;\n\n case 'two-column-split':\n body = `<div class=\"columns-2\">\\n<div>\\n\\n### ${c.leftHeader || 'Cách tiếp cận A'}\\n${c.leftCol || '- Điểm 1\\n- Điểm 2\\n- Điểm 3'}\\n\\n</div>\\n<div>\\n\\n### ${c.rightHeader || 'Cách tiếp cận B'}\\n${c.rightCol || '- Điểm 1\\n- Điểm 2\\n- Điểm 3'}\\n\\n</div>\\n</div>`;\n break;\n\n case 'code-explainer':\n body = `<div class=\"columns-2\">\\n<div>\\n\\n\\`\\`\\`${c.lang || 'ts'}\\n${c.code || '// Code snippet ở đây\\nconst example = true;'}\\n\\`\\`\\`\\n\\n</div>\\n<div>\\n\\n### 🔍 Điểm cốt lõi:\\n${c.notes || '1. **Phân tích dòng 1:** Khởi tạo\\n2. **Phân tích dòng 2:** Thực thi\\n3. **Lưu ý:** Điều kiện biên'}\\n\\n</div>\\n</div>`;\n break;\n\n case 'metrics-3-card':\n body = `<div class=\"columns-3\">\\n<div>\\n\\n# ${c.metric1Val || '99.9%'}\\n### ${c.metric1Title || 'Chỉ số 1'}\\n${c.metric1Desc || 'Mô tả ngắn gọn về chỉ số.'}\\n\\n</div>\\n<div>\\n\\n# ${c.metric2Val || '10x'}\\n### ${c.metric2Title || 'Chỉ số 2'}\\n${c.metric2Desc || 'Mô tả ngắn gọn về chỉ số.'}\\n\\n</div>\\n<div>\\n\\n# ${c.metric3Val || '0'}\\n### ${c.metric3Title || 'Chỉ số 3'}\\n${c.metric3Desc || 'Mô tả ngắn gọn về chỉ số.'}\\n\\n</div>\\n</div>`;\n break;\n\n case 'process-flow':\n body = `\\`\\`\\`mermaid\\n${c.mermaid || 'graph LR\\n A[Bước 1] --> B[Bước 2]\\n B --> C[Bước 3]\\n C --> D[Hoàn thành]'}\\n\\`\\`\\`\\n\\n${c.summary || '- **Giai đoạn 1:** Khởi động\\n- **Giai đoạn 2:** Xử lý dữ liệu\\n- **Giai đoạn 3:** Kết xuất kết quả'}`;\n break;\n\n case 'quote-highlight':\n body = `> \"${c.quote || 'Sự đơn giản là chìa khóa của độ tin cậy.'}\"\\n> \\n> — **${c.author || 'Danh ngôn công nghệ'}**`;\n break;\n\n case 'quiz-checkpoint':\n body = `> **Câu hỏi:** ${c.question || 'Phương án nào sau đây là tối ưu nhất?'}\\n\\n- **A.** ${c.optA || 'Lựa chọn A'}\\n- **B.** ${c.optB || 'Lựa chọn B (Chính xác)'}\\n- **C.** ${c.optC || 'Lựa chọn C'}\\n- **D.** ${c.optD || 'Lựa chọn D'}`;\n break;\n\n case 'tiered-practice-3cards':\n body = `<div class=\"columns-3\">\\n<div>\\n\\n### 🥉 Hạng Đồng (Bronze)\\n${c.bronze || '- Bài tập cơ bản\\n- 1 test case mẫu'}\\n\\n</div>\\n<div>\\n\\n### 🥈 Hạng Bạc (Silver)\\n${c.silver || '- Tối ưu thuật toán\\n- Xử lý điều kiện biên'}\\n\\n</div>\\n<div>\\n\\n### 🥇 Hạng Vàng (Gold)\\n${c.gold || '- Tính năng mở rộng\\n- Tự động hóa unit test'}\\n\\n</div>\\n</div>`;\n break;\n\n default:\n body = preset.markdownSnippet.replace(/^<!--[\\s\\S]*?-->\\n*/, '').replace(/^#\\s+[^\\n]+\\n*/, '').trim();\n }\n }\n\n const notes = params.presenterNotes && params.presenterNotes.length > 0\n ? `\\n\\n<!--\\nPresenter Notes:\\n${params.presenterNotes.map(n => `- ${n}`).join('\\n')}\\n-->`\n : `\\n\\n<!--\\nPresenter Notes:\\n- Giải thích khái niệm chính trên slide.\\n- Đặt câu hỏi tương tác cho cả lớp.\\n-->`;\n\n const slideMarkdown = `${layoutComment}\\n\\n## ${title}${body ? '\\n\\n' + body : ''}${notes}`;\n\n return {\n success: true,\n slideMarkdown,\n presetName: preset.name,\n };\n}\n\n/**\n * Execute: applySlideLayout\n */\nexport function executeApplySlideLayout(params: {\n markdown: string;\n slideIndex: number;\n presetId?: string;\n boxes?: SlideLayoutData['boxes'];\n}): { success: boolean; updatedMarkdown: string; error?: string } {\n let layoutData: SlideLayoutData | null = null;\n\n if (params.presetId) {\n const preset = getSlideLayoutPresetById(params.presetId);\n if (!preset) {\n return {\n success: false,\n updatedMarkdown: params.markdown,\n error: `Không tìm thấy preset với ID: \"${params.presetId}\"`,\n };\n }\n layoutData = preset.layout;\n } else if (params.boxes && params.boxes.length > 0) {\n layoutData = { boxes: params.boxes };\n }\n\n const updatedMarkdown = updateSlideLayoutInMarkdown(\n params.markdown,\n params.slideIndex,\n layoutData\n );\n\n return {\n success: true,\n updatedMarkdown,\n };\n}\n\n/**\n * Execute: updatePresenterNotes\n */\nexport function executeUpdatePresenterNotes(params: {\n markdown: string;\n slideIndex: number;\n notes: string[];\n}): { success: boolean; updatedMarkdown: string; error?: string } {\n const { frontmatter, slides } = splitMarkdownSlides(params.markdown);\n\n if (params.slideIndex < 0 || params.slideIndex >= slides.length) {\n return {\n success: false,\n updatedMarkdown: params.markdown,\n error: `Slide index ${params.slideIndex} ngoài phạm vi (tổng số slides: ${slides.length})`,\n };\n }\n\n let slideContent = slides[params.slideIndex];\n const notesCommentRegex = /<!--\\s*(?:Presenter Notes|Notes):\\s*([\\s\\S]*?)-->/i;\n const newNotesComment = `<!--\\nPresenter Notes:\\n${params.notes.map(n => `- ${n}`).join('\\n')}\\n-->`;\n\n if (notesCommentRegex.test(slideContent)) {\n slideContent = slideContent.replace(notesCommentRegex, newNotesComment);\n } else {\n slideContent = `${slideContent.trimEnd()}\\n\\n${newNotesComment}`;\n }\n\n slides[params.slideIndex] = slideContent;\n const joined = slides.join('\\n---\\n');\n const updatedMarkdown = frontmatter ? `${frontmatter}\\n\\n${joined}` : joined;\n\n return {\n success: true,\n updatedMarkdown,\n };\n}\n\n/**\n * Execute: generateDeckOutline (indexed by talk duration)\n */\nexport function executeGenerateDeckOutline(params: {\n topic: string;\n durationMins: number;\n audience: string;\n keyObjectives: string[];\n techStack?: string;\n}) {\n const d = params.durationMins;\n let targetSlideCount = 12;\n let formatLabel = '15 min (Short Talk)';\n\n if (d <= 7) {\n targetSlideCount = 6;\n formatLabel = '5 min (Lightning Talk)';\n } else if (d <= 20) {\n targetSlideCount = 14;\n formatLabel = '15 min (Short Talk)';\n } else if (d <= 35) {\n targetSlideCount = 28;\n formatLabel = '30 min (Conference Talk)';\n } else {\n targetSlideCount = 42;\n formatLabel = '45-60 min (Keynote / Workshop)';\n }\n\n return {\n topic: params.topic,\n audience: params.audience,\n durationMins: d,\n format: formatLabel,\n recommendedSlideCount: targetSlideCount,\n structureGuidelines: [\n 'Áp dụng nguyên tắc: Một ý tưởng duy nhất trên mỗi slide (One Idea Per Slide).',\n 'Giới hạn từ: Tối đa 40 từ trên mỗi card/cột để chống tràn chữ (Zero Scroll Invariant).',\n 'Tỷ lệ hiển thị: Chuẩn 16:9 với hệ tọa độ 1280x720.',\n 'Bắt buộc có khối Presenter Notes chứa: Talk track giảng viên + 1 câu hỏi tương tác cold-call.',\n ],\n suggestedOutline: [\n { slide: 1, type: 'title-hero', title: `🚀 ${params.topic}`, intent: 'Gây ấn tượng ban đầu và giới thiệu diễn giả' },\n { slide: 2, type: 'agenda-timeline', title: '🗺️ Lộ trình hoạt động', intent: 'Định hình cấu trúc thời gian và kết quả đầu ra' },\n { slide: 3, type: 'two-column-split', title: '⚡ Bối cảnh & Thử thách', intent: 'So sánh cách làm cũ vs vấn đề thực tế' },\n { slide: 4, type: 'process-flow', title: '🔄 Kiến trúc cốt lõi', intent: 'Sơ đồ luồng xử lý tổng quan' },\n { slide: 5, type: 'code-explainer', title: '💻 Phân tích mã nguồn', intent: 'Đi sâu vào implementation kỹ thuật' },\n { slide: 6, type: 'metrics-3-card', title: '📊 3 Chỉ số đo lường', intent: 'Định lượng hiệu năng và tính hiệu quả' },\n { slide: 7, type: 'tiered-practice-3cards', title: '🛠️ Thử thách phân hóa', intent: 'Thực hành tại chỗ theo 3 bậc Bronze-Silver-Gold' },\n { slide: 8, type: 'quiz-checkpoint', title: '🎯 Kiểm tra nhanh', intent: 'Đánh giá mức độ tiếp thu (Formative Checkpoint)' },\n { slide: 9, type: 'takeaways-summary', title: '🏁 Tổng kết cốt lõi', intent: '3 bài học rút ra và nhiệm vụ tiếp theo' },\n ].slice(0, Math.max(5, Math.min(targetSlideCount, 10))),\n };\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// @learnwell/presentation-kit — Slide Design Prompt Contract & System Invariants\n// \n// Modeled after battle-tested presentation orchestrators (e.g. slides-ai-plugin)\n// Provides rigorous invariants for LLM slide generation across web & PPTX.\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport const SLIDE_DESIGN_PROMPT_CONTRACT = `\n# SYSTEM MANDATE: PROFESSIONAL PRESENTATION & SLIDE DESIGN INVARIANTS\n\nYou are an expert Presentation Architect & Visual Designer for educational, technical, and executive decks.\nWhen generating or modifying Marp slide presentations, you MUST STRICTLY obey the following non-negotiable rules:\n\n---\n\n## 1. DURATION-INDEXED SLIDE PACING\nStructure decks based on allocated talk time (averaging 1.5 - 2 minutes per slide):\n- **5 min (Lightning Talk):** 5 - 7 slides [Hook -> 2-3 Core Points -> CTA / Summary]\n- **15 min (Short Tech Talk):** 12 - 16 slides [Title -> Agenda -> Hook -> 3-4 Concepts -> Lab/Demo -> Summary]\n- **30 min (Conference / Class):** 24 - 32 slides [Full 5E Learning Cycle + Interactive Formative Checkpoint]\n- **45-60 min (Keynote / Workshop):** 36 - 50 slides [Modular Micro-cycles + Tiered Hands-on Exercises]\n\n---\n\n## 2. THE \"ONE IDEA PER SLIDE\" RULE\n- Each slide communicates **EXACTLY ONE** pedagogical or architectural concept.\n- Never pack multiple distinct topics into a single slide.\n- If a concept has both theory and code, split into: (Slide A) Concept Diagram -> (Slide B) Code Walkthrough.\n\n---\n\n## 3. STRICT WORD BUDGET (ZERO-SCROLL INVARIANT)\n- **Hard Limit:** Maximum **35 - 40 words** per card or column.\n- Never write paragraphs longer than 2 sentences. Use structured bullets with bold anchor terms:\n - Format: \\`- **Khái niệm then chốt:** Mô tả súc tích trong 1 dòng.\\`\n- Vertical scrolling inside a slide is STRICTLY FORBIDDEN. Content must fit the 16:9 (1280x720) canvas cleanly.\n\n---\n\n## 4. TWO-COLUMN & CARD BALANCED LAYOUTS\n- Avoid centered vertical walls of text. Use responsive side-by-side card wrappers:\n \\`\\`\\`html\n <div class=\"columns-2\">\n <div>\n ### 🔴 Cũ / Thách Thức\n - ...\n </div>\n <div>\n ### 🟢 Mới / Giải Pháp\n - ...\n </div>\n </div>\n \\`\\`\\`\n- For 3 metrics or bronze/silver/gold differentiation, use \\`<div class=\"columns-3\">...</div>\\`.\n\n---\n\n## 5. MANDATORY PRESENTER NOTES (TEACHER TALK TRACK)\nEvery single slide MUST conclude with an HTML comment block containing:\n1. **Talk Track:** 2-3 sentences of what the speaker should say out loud.\n2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student.\n3. **Scaffolding Tip:** 1 hint if students look confused.\n\nExample:\n\\`\\`\\`markdown\n<!--\nPresenter Notes:\n- Trình bày điểm nghẽn lớn nhất trong việc mở rộng quy mô dữ liệu.\n- Cold-call: \"Em Nguyễn Văn B, nếu số lượng request tăng gấp 10 lần thì điểm nào sẽ sập đầu tiên?\"\n- Gợi ý gợi mở: Nhắc học viên nhớ lại khái niệm I/O bottleneck ở bài trước.\n-->\n\\`\\`\\`\n\n---\n\n## 6. MARP COMPATIBLE YAML LAYOUT HEADERS\nWhen a precise coordinate layout is specified, include the clean YAML block at the very top of the slide:\n\\`\\`\\`markdown\n<!-- layout:\n boxes:\n - id: heading\n target: h2\n pos: [80, 50, 1120, 70]\n fontSize: 2rem\n - id: col-left\n target: '.columns-2 > div:first-child'\n pos: [80, 150, 530, 510]\n - id: col-right\n target: '.columns-2 > div:last-child'\n pos: [670, 150, 530, 510]\n-->\n\\`\\`\\`\n`;\n"]}
1
+ {"version":3,"sources":["../../src/ai/schemas.ts","../../src/ai/tools.ts","../../src/ai/prompt.ts"],"names":["z","SLIDE_LAYOUT_PRESETS","getSlideLayoutPresetsByCategory","getSlideLayoutPresetById","serializeLayoutToComment","updateSlideLayoutInMarkdown","splitMarkdownSlides"],"mappings":"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","file":"index.cjs","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// @learnwell/presentation-kit — AI Tool Schemas (Zod)\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport { z } from 'zod';\n\nexport const listSlidePresetsSchema = z.object({\n category: z.enum([\n 'all',\n 'cover',\n 'content',\n 'split',\n 'code',\n 'metrics',\n 'diagram',\n 'quote',\n 'assessment',\n ]).optional().describe('Optional category filter for layout presets'),\n});\n\nexport const createSlideFromPresetSchema = z.object({\n presetId: z.string().describe(\n 'ID of the layout preset: title-hero, two-column-split, code-explainer, metrics-3-card, process-flow, quote-highlight, quiz-checkpoint, tiered-practice-3cards, agenda-timeline, takeaways-summary'\n ),\n title: z.string().describe('Slide heading or title'),\n subtitle: z.string().optional().describe('Optional subtitle or section context'),\n content: z.record(z.string()).optional().describe(\n 'Key-value pairs for preset sections. For two-column-split: leftCol, rightCol. For code-explainer: code, language, notes. For metrics-3-card: card1Title, card1Val, card1Desc, etc.'\n ),\n customMarkdownBody: z.string().optional().describe(\n 'Raw markdown body to place inside the layout container (overrides content key-value pairs if provided)'\n ),\n presenterNotes: z.array(z.string()).optional().describe(\n 'Teacher talk track, cold-call check questions, or scaffolding notes for this slide'\n ),\n});\n\nexport const applySlideLayoutSchema = z.object({\n markdown: z.string().describe('Full Markdown slide deck content'),\n slideIndex: z.number().int().min(0).describe('0-based index of the target slide to modify'),\n presetId: z.string().optional().describe('Optional preset ID to apply to this slide'),\n boxes: z.array(\n z.object({\n id: z.string(),\n target: z.string().optional(),\n pos: z.tuple([z.number(), z.number(), z.number(), z.number()]).describe('[x, y, width, height] in 1280x720 canvas coordinates'),\n fontSize: z.string().optional(),\n color: z.string().optional(),\n textAlign: z.enum(['left', 'center', 'right', 'justify']).optional(),\n style: z.string().optional(),\n })\n ).optional().describe('Custom boxes if not using presetId'),\n});\n\nexport const updatePresenterNotesSchema = z.object({\n markdown: z.string().describe('Full Markdown slide deck content'),\n slideIndex: z.number().int().min(0).describe('0-based index of the target slide'),\n notes: z.array(z.string()).describe('List of speaker notes / talk tracks to set for this slide'),\n});\n\nexport const generateDeckOutlineSchema = z.object({\n topic: z.string().describe('Main subject or topic of the presentation'),\n durationMins: z.number().int().min(3).max(120).default(15).describe('Estimated duration in minutes (5m: 5-7 slides, 15m: 12-18 slides, 30m: 25-35 slides)'),\n audience: z.string().describe('Target audience profile (e.g. Grade 10 students, junior developers, enterprise clients)'),\n keyObjectives: z.array(z.string()).describe('2-4 key learning or decision objectives'),\n techStack: z.string().optional().describe('Optional programming language, framework, or hardware kit'),\n});\n","// ═══════════════════════════════════════════════════════════════════════════════\n// @learnwell/presentation-kit — AI Tool Handlers\n// Pure execution handlers for Vercel AI SDK / OpenAI tool calls\n// ═══════════════════════════════════════════════════════════════════════════════\n\nimport {\n SLIDE_LAYOUT_PRESETS,\n getSlideLayoutPresetById,\n getSlideLayoutPresetsByCategory,\n type SlideLayoutCategory,\n} from '../core/layout/presets.js';\nimport {\n updateSlideLayoutInMarkdown,\n splitMarkdownSlides,\n serializeLayoutToComment,\n} from '../core/layout/serializer.js';\nimport type { SlideLayoutData } from '../types.js';\n\n/**\n * Execute: listSlidePresets\n */\nexport function executeListSlidePresets(params?: { category?: string }) {\n const category = params?.category;\n const presets = (!category || category === 'all')\n ? SLIDE_LAYOUT_PRESETS\n : getSlideLayoutPresetsByCategory(category as SlideLayoutCategory);\n\n return {\n count: presets.length,\n presets: presets.map(p => ({\n id: p.id,\n name: p.name,\n category: p.category,\n description: p.description,\n boxCount: p.layout.boxes.length,\n snippetPreview: p.markdownSnippet.split('\\n').slice(0, 8).join('\\n') + '\\n...',\n })),\n };\n}\n\n/**\n * Execute: createSlideFromPreset\n */\nexport function executeCreateSlideFromPreset(params: {\n presetId: string;\n title: string;\n subtitle?: string;\n content?: Record<string, string>;\n customMarkdownBody?: string;\n presenterNotes?: string[];\n}): { success: boolean; slideMarkdown: string; presetName?: string; error?: string } {\n const preset = getSlideLayoutPresetById(params.presetId);\n if (!preset) {\n return {\n success: false,\n slideMarkdown: '',\n error: `Preset with ID \"${params.presetId}\" not found. Use listSlidePresets to see available layout templates.`,\n };\n }\n\n const layoutComment = serializeLayoutToComment(preset.layout);\n const title = params.title;\n const subtitle = params.subtitle ? `\\n### ${params.subtitle}` : '';\n\n let body = params.customMarkdownBody;\n\n if (!body) {\n const c = params.content || {};\n switch (preset.id) {\n case 'title-hero':\n body = `${subtitle}\\n\\n**Presenter:** ${c.speaker || 'Lead Instructor'} | **Duration:** ${c.duration || '45 mins'} | **Topic:** ${c.topic || title}`;\n break;\n\n case 'two-column-split':\n body = `<div class=\"columns-2\">\\n<div>\\n\\n### ${c.leftHeader || 'Approach A'}\\n${c.leftCol || '- Point 1\\n- Point 2\\n- Point 3'}\\n\\n</div>\\n<div>\\n\\n### ${c.rightHeader || 'Approach B'}\\n${c.rightCol || '- Point 1\\n- Point 2\\n- Point 3'}\\n\\n</div>\\n</div>`;\n break;\n\n case 'code-explainer':\n body = `<div class=\"columns-2\">\\n<div>\\n\\n\\`\\`\\`${c.lang || 'ts'}\\n${c.code || '// Core implementation logic\\nconst isValid = true;'}\\n\\`\\`\\`\\n\\n</div>\\n<div>\\n\\n### 🔍 Key Invariants:\\n${c.notes || '1. **Validation:** Checks payload before processing\\n2. **Execution:** Enforces deterministic state\\n3. **Resilience:** Handles edge case errors'}\\n\\n</div>\\n</div>`;\n break;\n\n case 'metrics-3-card':\n body = `<div class=\"columns-3\">\\n<div>\\n\\n# ${c.metric1Val || '99.9%'}\\n### ${c.metric1Title || 'Availability'}\\n${c.metric1Desc || 'Automated multi-region failover routing.'}\\n\\n</div>\\n<div>\\n\\n# ${c.metric2Val || '10x'}\\n### ${c.metric2Title || 'Throughput'}\\n${c.metric2Desc || 'Sub-millisecond processing latency.'}\\n\\n</div>\\n<div>\\n\\n# ${c.metric3Val || '0'}\\n### ${c.metric3Title || 'Breaches'}\\n${c.metric3Desc || 'Continuous SOC2 compliance auditing.'}\\n\\n</div>\\n</div>`;\n break;\n\n case 'process-flow':\n body = `\\`\\`\\`mermaid\\n${c.mermaid || 'graph LR\\n A[1. Ingress] --> B[2. Gateway]\\n B --> C[3. Service]\\n C --> D[4. Storage]'}\\n\\`\\`\\`\\n\\n${c.summary || '- **Phase 1 & 2:** Client connection and load balancing.\\n- **Phase 3 & 4:** Business logic execution and data commit.'}`;\n break;\n\n case 'quote-highlight':\n body = `> \"${c.quote || 'Simplicity is prerequisite for reliability.'}\"\\n> \\n> — **${c.author || 'Architecture Principle'}**`;\n break;\n\n case 'quiz-checkpoint':\n body = `> **Question:** ${c.question || 'Which architecture pattern best ensures reliable message delivery?'}\\n\\n- **A.** ${c.optA || 'Direct synchronous HTTP request with short timeout'}\\n- **B.** ${c.optB || 'Persistent Message Queue with Dead-Letter Queue (Correct)'}\\n- **C.** ${c.optC || 'In-memory client cache without persistence'}\\n- **D.** ${c.optD || 'Silently dropping failed packets'}`;\n break;\n\n case 'tiered-practice-3cards':\n body = `<div class=\"columns-3\">\\n<div>\\n\\n### 🥉 Bronze Tier\\n${c.bronze || '- Implement baseline function\\n- Pass 2 sample unit tests'}\\n\\n</div>\\n<div>\\n\\n### 🥈 Silver Tier\\n${c.silver || '- Add boundary error handling\\n- Optimize algorithm complexity'}\\n\\n</div>\\n<div>\\n\\n### 🥇 Gold Tier\\n${c.gold || '- Design extension feature\\n- Write automated integration tests'}\\n\\n</div>\\n</div>`;\n break;\n\n default:\n body = preset.markdownSnippet.replace(/^<!--[\\s\\S]*?-->\\n*/, '').replace(/^#\\s+[^\\n]+\\n*/, '').trim();\n }\n }\n\n const notes = params.presenterNotes && params.presenterNotes.length > 0\n ? `\\n\\n<!--\\nPresenter Notes:\\n${params.presenterNotes.map(n => `- ${n}`).join('\\n')}\\n-->`\n : `\\n\\n<!--\\nPresenter Notes:\\n- Explain the primary concept on this slide.\\n- Ask a diagnostic cold-call question to check comprehension.\\n-->`;\n\n const slideMarkdown = `${layoutComment}\\n\\n## ${title}${body ? '\\n\\n' + body : ''}${notes}`;\n\n return {\n success: true,\n slideMarkdown,\n presetName: preset.name,\n };\n}\n\n/**\n * Execute: applySlideLayout\n */\nexport function executeApplySlideLayout(params: {\n markdown: string;\n slideIndex: number;\n presetId?: string;\n boxes?: SlideLayoutData['boxes'];\n}): { success: boolean; updatedMarkdown: string; error?: string } {\n let layoutData: SlideLayoutData | null = null;\n\n if (params.presetId) {\n const preset = getSlideLayoutPresetById(params.presetId);\n if (!preset) {\n return {\n success: false,\n updatedMarkdown: params.markdown,\n error: `Preset with ID \"${params.presetId}\" not found.`,\n };\n }\n layoutData = preset.layout;\n } else if (params.boxes && params.boxes.length > 0) {\n layoutData = { boxes: params.boxes };\n }\n\n const updatedMarkdown = updateSlideLayoutInMarkdown(\n params.markdown,\n params.slideIndex,\n layoutData\n );\n\n return {\n success: true,\n updatedMarkdown,\n };\n}\n\n/**\n * Execute: updatePresenterNotes\n */\nexport function executeUpdatePresenterNotes(params: {\n markdown: string;\n slideIndex: number;\n notes: string[];\n}): { success: boolean; updatedMarkdown: string; error?: string } {\n const { frontmatter, slides } = splitMarkdownSlides(params.markdown);\n\n if (params.slideIndex < 0 || params.slideIndex >= slides.length) {\n return {\n success: false,\n updatedMarkdown: params.markdown,\n error: `Slide index ${params.slideIndex} out of bounds (total slides: ${slides.length})`,\n };\n }\n\n let slideContent = slides[params.slideIndex];\n const notesCommentRegex = /<!--\\s*(?:Presenter Notes|Notes):\\s*([\\s\\S]*?)-->/i;\n const newNotesComment = `<!--\\nPresenter Notes:\\n${params.notes.map(n => `- ${n}`).join('\\n')}\\n-->`;\n\n if (notesCommentRegex.test(slideContent)) {\n slideContent = slideContent.replace(notesCommentRegex, newNotesComment);\n } else {\n slideContent = `${slideContent.trimEnd()}\\n\\n${newNotesComment}`;\n }\n\n slides[params.slideIndex] = slideContent;\n const joined = slides.join('\\n---\\n');\n const updatedMarkdown = frontmatter ? `${frontmatter}\\n\\n${joined}` : joined;\n\n return {\n success: true,\n updatedMarkdown,\n };\n}\n\n/**\n * Execute: generateDeckOutline (indexed by talk duration)\n */\nexport function executeGenerateDeckOutline(params: {\n topic: string;\n durationMins: number;\n audience: string;\n keyObjectives: string[];\n techStack?: string;\n}) {\n const d = params.durationMins;\n let targetSlideCount = 12;\n let formatLabel = '15 min (Short Talk)';\n\n if (d <= 7) {\n targetSlideCount = 6;\n formatLabel = '5 min (Lightning Talk)';\n } else if (d <= 20) {\n targetSlideCount = 14;\n formatLabel = '15 min (Short Talk)';\n } else if (d <= 35) {\n targetSlideCount = 28;\n formatLabel = '30 min (Conference Talk)';\n } else {\n targetSlideCount = 42;\n formatLabel = '45-60 min (Keynote / Workshop)';\n }\n\n return {\n topic: params.topic,\n audience: params.audience,\n durationMins: d,\n format: formatLabel,\n recommendedSlideCount: targetSlideCount,\n structureGuidelines: [\n 'Apply the \"One Idea Per Slide\" invariant.',\n 'Enforce Word Budget: Maximum 40 words per card or column (Zero-Scroll Invariant).',\n 'Target 16:9 aspect ratio in 1280x720 coordinate space.',\n 'Every slide must conclude with Presenter Notes: Teacher talk track + 1 diagnostic cold-call question.',\n ],\n suggestedOutline: [\n { slide: 1, type: 'title-hero', title: `🚀 ${params.topic}`, intent: 'Opening hook and speaker credentialing' },\n { slide: 2, type: 'agenda-timeline', title: '🗺️ Session Milestones', intent: 'Set time budget expectations and learning deliverables' },\n { slide: 3, type: 'two-column-split', title: '⚡ Problem vs Opportunity', intent: 'Contrast legacy bottlenecks against the modern solution' },\n { slide: 4, type: 'process-flow', title: '🔄 Architectural Flow', intent: 'High-level system topology and sequence diagram' },\n { slide: 5, type: 'code-explainer', title: '💻 Core Code Walkthrough', intent: 'Deep-dive into production implementation logic' },\n { slide: 6, type: 'metrics-3-card', title: '📊 Benchmark Results', intent: 'Quantify performance and reliability gains' },\n { slide: 7, type: 'tiered-practice-3cards', title: '🛠️ Hands-On Challenge', intent: 'Differentiated practice across Bronze, Silver, and Gold tiers' },\n { slide: 8, type: 'quiz-checkpoint', title: '🎯 Formative Checkpoint', intent: 'Real-time diagnostic voting to verify mastery' },\n { slide: 9, type: 'takeaways-summary', title: '🏁 Key Takeaways', intent: 'Synthesis of 3 core lessons and next action items' },\n ].slice(0, Math.max(5, Math.min(targetSlideCount, 10))),\n };\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// @learnwell/presentation-kit — Slide Design Prompt Contract & System Invariants\n// \n// Modeled after battle-tested presentation orchestrators (e.g. slides-ai-plugin)\n// Provides rigorous invariants for LLM slide generation across web & PPTX.\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport const SLIDE_DESIGN_PROMPT_CONTRACT = `\n# SYSTEM MANDATE: PROFESSIONAL PRESENTATION & SLIDE DESIGN INVARIANTS\n\nYou are an expert Presentation Architect & Visual Designer for educational, technical, and executive decks.\nWhen generating or modifying Marp slide presentations, you MUST STRICTLY obey the following non-negotiable rules:\n\n---\n\n## 1. DURATION-INDEXED SLIDE PACING\nStructure decks based on allocated talk time (averaging 1.5 - 2 minutes per slide):\n- **5 min (Lightning Talk):** 5 - 7 slides [Hook -> 2-3 Core Points -> CTA / Summary]\n- **15 min (Short Tech Talk):** 12 - 16 slides [Title -> Agenda -> Hook -> 3-4 Concepts -> Lab/Demo -> Summary]\n- **30 min (Conference / Class):** 24 - 32 slides [Full 5E Learning Cycle + Interactive Formative Checkpoint]\n- **45-60 min (Keynote / Workshop):** 36 - 50 slides [Modular Micro-cycles + Tiered Hands-on Exercises]\n\n---\n\n## 2. THE \"ONE IDEA PER SLIDE\" RULE\n- Each slide communicates **EXACTLY ONE** pedagogical or architectural concept.\n- Never pack multiple distinct topics into a single slide.\n- If a concept has both theory and code, split into: (Slide A) Concept Diagram -> (Slide B) Code Walkthrough.\n\n---\n\n## 3. STRICT WORD BUDGET (ZERO-SCROLL INVARIANT)\n- **Hard Limit:** Maximum **35 - 40 words** per card or column.\n- Never write paragraphs longer than 2 sentences. Use structured bullets with bold anchor terms:\n - Format: \\`- **Key Concept:** Concise explanation in a single line.\\`\n- Vertical scrolling inside a slide is STRICTLY FORBIDDEN. Content must fit the 16:9 (1280x720) canvas cleanly.\n\n---\n\n## 4. TWO-COLUMN & CARD BALANCED LAYOUTS\n- Avoid centered vertical walls of text. Use responsive side-by-side card wrappers:\n \\`\\`\\`html\n <div class=\"columns-2\">\n <div>\n ### 🔴 Legacy / Challenge\n - High idle compute overhead\n - Cascading timeout failures\n </div>\n <div>\n ### 🟢 Modern / Solution\n - Event-driven webhook streams\n - Automatic queue backpressure\n </div>\n </div>\n \\`\\`\\`\n- For 3 metrics or bronze/silver/gold differentiation, use \\`<div class=\"columns-3\">...</div>\\`.\n\n---\n\n## 5. MANDATORY PRESENTER NOTES (TEACHER TALK TRACK)\nEvery single slide MUST conclude with an HTML comment block containing:\n1. **Talk Track:** 2-3 sentences of what the speaker should say out loud.\n2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student or attendee.\n3. **Scaffolding Tip:** 1 hint or real-world analogy if learners look confused.\n\nExample:\n\\`\\`\\`markdown\n<!--\nPresenter Notes:\n- Walk through the primary bottleneck when scaling database writes under high concurrency.\n- Cold-call: \"Alex, if traffic spikes 10x in 1 minute, which subsystem will experience lock contention first?\"\n- Scaffolding tip: Remind the room of the I/O saturation trade-off discussed in the previous module.\n-->\n\\`\\`\\`\n\n---\n\n## 6. MARP COMPATIBLE YAML LAYOUT HEADERS\nWhen a precise coordinate layout is specified, include the clean YAML block at the very top of the slide:\n\\`\\`\\`markdown\n<!-- layout:\n boxes:\n - id: heading\n target: h2\n pos: [80, 50, 1120, 70]\n fontSize: 2rem\n - id: col-left\n target: '.columns-2 > div:first-child'\n pos: [80, 150, 530, 510]\n - id: col-right\n target: '.columns-2 > div:last-child'\n pos: [670, 150, 530, 510]\n-->\n\\`\\`\\`\n`;\n"]}
@@ -201,6 +201,6 @@ declare function executeGenerateDeckOutline(params: {
201
201
  }[];
202
202
  };
203
203
 
204
- declare const SLIDE_DESIGN_PROMPT_CONTRACT = "\n# SYSTEM MANDATE: PROFESSIONAL PRESENTATION & SLIDE DESIGN INVARIANTS\n\nYou are an expert Presentation Architect & Visual Designer for educational, technical, and executive decks.\nWhen generating or modifying Marp slide presentations, you MUST STRICTLY obey the following non-negotiable rules:\n\n---\n\n## 1. DURATION-INDEXED SLIDE PACING\nStructure decks based on allocated talk time (averaging 1.5 - 2 minutes per slide):\n- **5 min (Lightning Talk):** 5 - 7 slides [Hook -> 2-3 Core Points -> CTA / Summary]\n- **15 min (Short Tech Talk):** 12 - 16 slides [Title -> Agenda -> Hook -> 3-4 Concepts -> Lab/Demo -> Summary]\n- **30 min (Conference / Class):** 24 - 32 slides [Full 5E Learning Cycle + Interactive Formative Checkpoint]\n- **45-60 min (Keynote / Workshop):** 36 - 50 slides [Modular Micro-cycles + Tiered Hands-on Exercises]\n\n---\n\n## 2. THE \"ONE IDEA PER SLIDE\" RULE\n- Each slide communicates **EXACTLY ONE** pedagogical or architectural concept.\n- Never pack multiple distinct topics into a single slide.\n- If a concept has both theory and code, split into: (Slide A) Concept Diagram -> (Slide B) Code Walkthrough.\n\n---\n\n## 3. STRICT WORD BUDGET (ZERO-SCROLL INVARIANT)\n- **Hard Limit:** Maximum **35 - 40 words** per card or column.\n- Never write paragraphs longer than 2 sentences. Use structured bullets with bold anchor terms:\n - Format: `- **Kh\u00E1i ni\u1EC7m then ch\u1ED1t:** M\u00F4 t\u1EA3 s\u00FAc t\u00EDch trong 1 d\u00F2ng.`\n- Vertical scrolling inside a slide is STRICTLY FORBIDDEN. Content must fit the 16:9 (1280x720) canvas cleanly.\n\n---\n\n## 4. TWO-COLUMN & CARD BALANCED LAYOUTS\n- Avoid centered vertical walls of text. Use responsive side-by-side card wrappers:\n ```html\n <div class=\"columns-2\">\n <div>\n ### \uD83D\uDD34 C\u0169 / Th\u00E1ch Th\u1EE9c\n - ...\n </div>\n <div>\n ### \uD83D\uDFE2 M\u1EDBi / Gi\u1EA3i Ph\u00E1p\n - ...\n </div>\n </div>\n ```\n- For 3 metrics or bronze/silver/gold differentiation, use `<div class=\"columns-3\">...</div>`.\n\n---\n\n## 5. MANDATORY PRESENTER NOTES (TEACHER TALK TRACK)\nEvery single slide MUST conclude with an HTML comment block containing:\n1. **Talk Track:** 2-3 sentences of what the speaker should say out loud.\n2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student.\n3. **Scaffolding Tip:** 1 hint if students look confused.\n\nExample:\n```markdown\n<!--\nPresenter Notes:\n- Tr\u00ECnh b\u00E0y \u0111i\u1EC3m ngh\u1EBDn l\u1EDBn nh\u1EA5t trong vi\u1EC7c m\u1EDF r\u1ED9ng quy m\u00F4 d\u1EEF li\u1EC7u.\n- Cold-call: \"Em Nguy\u1EC5n V\u0103n B, n\u1EBFu s\u1ED1 l\u01B0\u1EE3ng request t\u0103ng g\u1EA5p 10 l\u1EA7n th\u00EC \u0111i\u1EC3m n\u00E0o s\u1EBD s\u1EADp \u0111\u1EA7u ti\u00EAn?\"\n- G\u1EE3i \u00FD g\u1EE3i m\u1EDF: Nh\u1EAFc h\u1ECDc vi\u00EAn nh\u1EDB l\u1EA1i kh\u00E1i ni\u1EC7m I/O bottleneck \u1EDF b\u00E0i tr\u01B0\u1EDBc.\n-->\n```\n\n---\n\n## 6. MARP COMPATIBLE YAML LAYOUT HEADERS\nWhen a precise coordinate layout is specified, include the clean YAML block at the very top of the slide:\n```markdown\n<!-- layout:\n boxes:\n - id: heading\n target: h2\n pos: [80, 50, 1120, 70]\n fontSize: 2rem\n - id: col-left\n target: '.columns-2 > div:first-child'\n pos: [80, 150, 530, 510]\n - id: col-right\n target: '.columns-2 > div:last-child'\n pos: [670, 150, 530, 510]\n-->\n```\n";
204
+ declare const SLIDE_DESIGN_PROMPT_CONTRACT = "\n# SYSTEM MANDATE: PROFESSIONAL PRESENTATION & SLIDE DESIGN INVARIANTS\n\nYou are an expert Presentation Architect & Visual Designer for educational, technical, and executive decks.\nWhen generating or modifying Marp slide presentations, you MUST STRICTLY obey the following non-negotiable rules:\n\n---\n\n## 1. DURATION-INDEXED SLIDE PACING\nStructure decks based on allocated talk time (averaging 1.5 - 2 minutes per slide):\n- **5 min (Lightning Talk):** 5 - 7 slides [Hook -> 2-3 Core Points -> CTA / Summary]\n- **15 min (Short Tech Talk):** 12 - 16 slides [Title -> Agenda -> Hook -> 3-4 Concepts -> Lab/Demo -> Summary]\n- **30 min (Conference / Class):** 24 - 32 slides [Full 5E Learning Cycle + Interactive Formative Checkpoint]\n- **45-60 min (Keynote / Workshop):** 36 - 50 slides [Modular Micro-cycles + Tiered Hands-on Exercises]\n\n---\n\n## 2. THE \"ONE IDEA PER SLIDE\" RULE\n- Each slide communicates **EXACTLY ONE** pedagogical or architectural concept.\n- Never pack multiple distinct topics into a single slide.\n- If a concept has both theory and code, split into: (Slide A) Concept Diagram -> (Slide B) Code Walkthrough.\n\n---\n\n## 3. STRICT WORD BUDGET (ZERO-SCROLL INVARIANT)\n- **Hard Limit:** Maximum **35 - 40 words** per card or column.\n- Never write paragraphs longer than 2 sentences. Use structured bullets with bold anchor terms:\n - Format: `- **Key Concept:** Concise explanation in a single line.`\n- Vertical scrolling inside a slide is STRICTLY FORBIDDEN. Content must fit the 16:9 (1280x720) canvas cleanly.\n\n---\n\n## 4. TWO-COLUMN & CARD BALANCED LAYOUTS\n- Avoid centered vertical walls of text. Use responsive side-by-side card wrappers:\n ```html\n <div class=\"columns-2\">\n <div>\n ### \uD83D\uDD34 Legacy / Challenge\n - High idle compute overhead\n - Cascading timeout failures\n </div>\n <div>\n ### \uD83D\uDFE2 Modern / Solution\n - Event-driven webhook streams\n - Automatic queue backpressure\n </div>\n </div>\n ```\n- For 3 metrics or bronze/silver/gold differentiation, use `<div class=\"columns-3\">...</div>`.\n\n---\n\n## 5. MANDATORY PRESENTER NOTES (TEACHER TALK TRACK)\nEvery single slide MUST conclude with an HTML comment block containing:\n1. **Talk Track:** 2-3 sentences of what the speaker should say out loud.\n2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student or attendee.\n3. **Scaffolding Tip:** 1 hint or real-world analogy if learners look confused.\n\nExample:\n```markdown\n<!--\nPresenter Notes:\n- Walk through the primary bottleneck when scaling database writes under high concurrency.\n- Cold-call: \"Alex, if traffic spikes 10x in 1 minute, which subsystem will experience lock contention first?\"\n- Scaffolding tip: Remind the room of the I/O saturation trade-off discussed in the previous module.\n-->\n```\n\n---\n\n## 6. MARP COMPATIBLE YAML LAYOUT HEADERS\nWhen a precise coordinate layout is specified, include the clean YAML block at the very top of the slide:\n```markdown\n<!-- layout:\n boxes:\n - id: heading\n target: h2\n pos: [80, 50, 1120, 70]\n fontSize: 2rem\n - id: col-left\n target: '.columns-2 > div:first-child'\n pos: [80, 150, 530, 510]\n - id: col-right\n target: '.columns-2 > div:last-child'\n pos: [670, 150, 530, 510]\n-->\n```\n";
205
205
 
206
206
  export { SLIDE_DESIGN_PROMPT_CONTRACT, applySlideLayoutSchema, createSlideFromPresetSchema, executeApplySlideLayout, executeCreateSlideFromPreset, executeGenerateDeckOutline, executeListSlidePresets, executeUpdatePresenterNotes, generateDeckOutlineSchema, listSlidePresetsSchema, updatePresenterNotesSchema };
@@ -201,6 +201,6 @@ declare function executeGenerateDeckOutline(params: {
201
201
  }[];
202
202
  };
203
203
 
204
- declare const SLIDE_DESIGN_PROMPT_CONTRACT = "\n# SYSTEM MANDATE: PROFESSIONAL PRESENTATION & SLIDE DESIGN INVARIANTS\n\nYou are an expert Presentation Architect & Visual Designer for educational, technical, and executive decks.\nWhen generating or modifying Marp slide presentations, you MUST STRICTLY obey the following non-negotiable rules:\n\n---\n\n## 1. DURATION-INDEXED SLIDE PACING\nStructure decks based on allocated talk time (averaging 1.5 - 2 minutes per slide):\n- **5 min (Lightning Talk):** 5 - 7 slides [Hook -> 2-3 Core Points -> CTA / Summary]\n- **15 min (Short Tech Talk):** 12 - 16 slides [Title -> Agenda -> Hook -> 3-4 Concepts -> Lab/Demo -> Summary]\n- **30 min (Conference / Class):** 24 - 32 slides [Full 5E Learning Cycle + Interactive Formative Checkpoint]\n- **45-60 min (Keynote / Workshop):** 36 - 50 slides [Modular Micro-cycles + Tiered Hands-on Exercises]\n\n---\n\n## 2. THE \"ONE IDEA PER SLIDE\" RULE\n- Each slide communicates **EXACTLY ONE** pedagogical or architectural concept.\n- Never pack multiple distinct topics into a single slide.\n- If a concept has both theory and code, split into: (Slide A) Concept Diagram -> (Slide B) Code Walkthrough.\n\n---\n\n## 3. STRICT WORD BUDGET (ZERO-SCROLL INVARIANT)\n- **Hard Limit:** Maximum **35 - 40 words** per card or column.\n- Never write paragraphs longer than 2 sentences. Use structured bullets with bold anchor terms:\n - Format: `- **Kh\u00E1i ni\u1EC7m then ch\u1ED1t:** M\u00F4 t\u1EA3 s\u00FAc t\u00EDch trong 1 d\u00F2ng.`\n- Vertical scrolling inside a slide is STRICTLY FORBIDDEN. Content must fit the 16:9 (1280x720) canvas cleanly.\n\n---\n\n## 4. TWO-COLUMN & CARD BALANCED LAYOUTS\n- Avoid centered vertical walls of text. Use responsive side-by-side card wrappers:\n ```html\n <div class=\"columns-2\">\n <div>\n ### \uD83D\uDD34 C\u0169 / Th\u00E1ch Th\u1EE9c\n - ...\n </div>\n <div>\n ### \uD83D\uDFE2 M\u1EDBi / Gi\u1EA3i Ph\u00E1p\n - ...\n </div>\n </div>\n ```\n- For 3 metrics or bronze/silver/gold differentiation, use `<div class=\"columns-3\">...</div>`.\n\n---\n\n## 5. MANDATORY PRESENTER NOTES (TEACHER TALK TRACK)\nEvery single slide MUST conclude with an HTML comment block containing:\n1. **Talk Track:** 2-3 sentences of what the speaker should say out loud.\n2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student.\n3. **Scaffolding Tip:** 1 hint if students look confused.\n\nExample:\n```markdown\n<!--\nPresenter Notes:\n- Tr\u00ECnh b\u00E0y \u0111i\u1EC3m ngh\u1EBDn l\u1EDBn nh\u1EA5t trong vi\u1EC7c m\u1EDF r\u1ED9ng quy m\u00F4 d\u1EEF li\u1EC7u.\n- Cold-call: \"Em Nguy\u1EC5n V\u0103n B, n\u1EBFu s\u1ED1 l\u01B0\u1EE3ng request t\u0103ng g\u1EA5p 10 l\u1EA7n th\u00EC \u0111i\u1EC3m n\u00E0o s\u1EBD s\u1EADp \u0111\u1EA7u ti\u00EAn?\"\n- G\u1EE3i \u00FD g\u1EE3i m\u1EDF: Nh\u1EAFc h\u1ECDc vi\u00EAn nh\u1EDB l\u1EA1i kh\u00E1i ni\u1EC7m I/O bottleneck \u1EDF b\u00E0i tr\u01B0\u1EDBc.\n-->\n```\n\n---\n\n## 6. MARP COMPATIBLE YAML LAYOUT HEADERS\nWhen a precise coordinate layout is specified, include the clean YAML block at the very top of the slide:\n```markdown\n<!-- layout:\n boxes:\n - id: heading\n target: h2\n pos: [80, 50, 1120, 70]\n fontSize: 2rem\n - id: col-left\n target: '.columns-2 > div:first-child'\n pos: [80, 150, 530, 510]\n - id: col-right\n target: '.columns-2 > div:last-child'\n pos: [670, 150, 530, 510]\n-->\n```\n";
204
+ declare const SLIDE_DESIGN_PROMPT_CONTRACT = "\n# SYSTEM MANDATE: PROFESSIONAL PRESENTATION & SLIDE DESIGN INVARIANTS\n\nYou are an expert Presentation Architect & Visual Designer for educational, technical, and executive decks.\nWhen generating or modifying Marp slide presentations, you MUST STRICTLY obey the following non-negotiable rules:\n\n---\n\n## 1. DURATION-INDEXED SLIDE PACING\nStructure decks based on allocated talk time (averaging 1.5 - 2 minutes per slide):\n- **5 min (Lightning Talk):** 5 - 7 slides [Hook -> 2-3 Core Points -> CTA / Summary]\n- **15 min (Short Tech Talk):** 12 - 16 slides [Title -> Agenda -> Hook -> 3-4 Concepts -> Lab/Demo -> Summary]\n- **30 min (Conference / Class):** 24 - 32 slides [Full 5E Learning Cycle + Interactive Formative Checkpoint]\n- **45-60 min (Keynote / Workshop):** 36 - 50 slides [Modular Micro-cycles + Tiered Hands-on Exercises]\n\n---\n\n## 2. THE \"ONE IDEA PER SLIDE\" RULE\n- Each slide communicates **EXACTLY ONE** pedagogical or architectural concept.\n- Never pack multiple distinct topics into a single slide.\n- If a concept has both theory and code, split into: (Slide A) Concept Diagram -> (Slide B) Code Walkthrough.\n\n---\n\n## 3. STRICT WORD BUDGET (ZERO-SCROLL INVARIANT)\n- **Hard Limit:** Maximum **35 - 40 words** per card or column.\n- Never write paragraphs longer than 2 sentences. Use structured bullets with bold anchor terms:\n - Format: `- **Key Concept:** Concise explanation in a single line.`\n- Vertical scrolling inside a slide is STRICTLY FORBIDDEN. Content must fit the 16:9 (1280x720) canvas cleanly.\n\n---\n\n## 4. TWO-COLUMN & CARD BALANCED LAYOUTS\n- Avoid centered vertical walls of text. Use responsive side-by-side card wrappers:\n ```html\n <div class=\"columns-2\">\n <div>\n ### \uD83D\uDD34 Legacy / Challenge\n - High idle compute overhead\n - Cascading timeout failures\n </div>\n <div>\n ### \uD83D\uDFE2 Modern / Solution\n - Event-driven webhook streams\n - Automatic queue backpressure\n </div>\n </div>\n ```\n- For 3 metrics or bronze/silver/gold differentiation, use `<div class=\"columns-3\">...</div>`.\n\n---\n\n## 5. MANDATORY PRESENTER NOTES (TEACHER TALK TRACK)\nEvery single slide MUST conclude with an HTML comment block containing:\n1. **Talk Track:** 2-3 sentences of what the speaker should say out loud.\n2. **Cold-Call Check Question:** 1 diagnostic question to ask a specific student or attendee.\n3. **Scaffolding Tip:** 1 hint or real-world analogy if learners look confused.\n\nExample:\n```markdown\n<!--\nPresenter Notes:\n- Walk through the primary bottleneck when scaling database writes under high concurrency.\n- Cold-call: \"Alex, if traffic spikes 10x in 1 minute, which subsystem will experience lock contention first?\"\n- Scaffolding tip: Remind the room of the I/O saturation trade-off discussed in the previous module.\n-->\n```\n\n---\n\n## 6. MARP COMPATIBLE YAML LAYOUT HEADERS\nWhen a precise coordinate layout is specified, include the clean YAML block at the very top of the slide:\n```markdown\n<!-- layout:\n boxes:\n - id: heading\n target: h2\n pos: [80, 50, 1120, 70]\n fontSize: 2rem\n - id: col-left\n target: '.columns-2 > div:first-child'\n pos: [80, 150, 530, 510]\n - id: col-right\n target: '.columns-2 > div:last-child'\n pos: [670, 150, 530, 510]\n-->\n```\n";
205
205
 
206
206
  export { SLIDE_DESIGN_PROMPT_CONTRACT, applySlideLayoutSchema, createSlideFromPresetSchema, executeApplySlideLayout, executeCreateSlideFromPreset, executeGenerateDeckOutline, executeListSlidePresets, executeUpdatePresenterNotes, generateDeckOutlineSchema, listSlidePresetsSchema, updatePresenterNotesSchema };