@lofcz/pptist 2.0.13 → 2.0.15

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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@lofcz/pptist",
4
- "packageVersion": "2.0.13",
5
- "generatedAt": "2026-06-02T07:12:26.717Z",
6
- "summary": "Authoring guidance for the PPTist agentic bridge. The fast, reliable way to build a deck: (1) pick ONE built-in presentation template (the same styles as the template picker template_1 template_8) with deck.applyTemplate, (2) read templates.slidesCatalog for that template's slide slugs grouped by type (cover, contents, transition, content, end), then (3) insert slides with slides.insertFromTemplate and edit text via text.setMarkdown. Do NOT build decks from blank slides.create or hand-placed elements unless no template slide fits. Content is Markdown or plain text — never hand-written HTML. Pair this with the machine schema (command payload/return types) in the same manifest.",
7
- "commandCount": 173,
4
+ "packageVersion": "2.0.15",
5
+ "generatedAt": "2026-06-17T04:24:25.505Z",
6
+ "summary": "Authoring guidance for the PPTist agentic bridge. The recommended way to build a deck from scratch: (1) pick ONE visual identity with styles.catalog -> deck.applyStyle (academic | minimal | bold | playful), then (2) for each slide pick a recipe from layouts.catalog and add it with slides.createFromLayout({ layoutId, slots }) — the engine themes, positions AND auto-fits every text box (via responsive measurement) so content never overflows. Author slot content as Markdown/plain text or structured values (arrays for bullets, { labels, series } for charts) never hand-written HTML. Alternative: for pixel-perfect branded decks, use the built-in templates flow (deck.applyTemplate + slides.insertFromTemplate). Avoid blank slides.create / hand-placed elements unless neither a layout nor a template slide fits. Pair this with the machine schema (command payload/return types) in the same manifest.",
7
+ "commandCount": 177,
8
8
  "designSystem": {
9
- "summary": "PPTist lays elements out in a fixed pixel coordinate space, not inches. Prefer built-in templates (deck.applyTemplate + slides.insertFromTemplate) so colors, contrast, fonts and layout come from the official template library instead of being hand-picked. These tokens describe the *fallback* defaults for manual placement only.",
9
+ "summary": "PPTist lays elements out in a fixed pixel coordinate space, not inches. Prefer the styles + layouts flow (deck.applyStyle + slides.createFromLayout) or, for branded decks, built-in templates (deck.applyTemplate + slides.insertFromTemplate) so colors, contrast, fonts and layout are chosen for you instead of hand-picked. These tokens describe the *fallback* defaults for manual placement only.",
10
10
  "coordinateSystem": {
11
11
  "summary": "The default 16:9 canvas is 1000 x 562.5 px (viewport.size = 1000, viewport.ratio = 0.5625). Origin (0,0) is the top-left corner. Every element has left, top, width, height in px and rotate in degrees.",
12
12
  "notes": [
@@ -48,7 +48,7 @@
48
48
  "domains": [
49
49
  {
50
50
  "id": "deck",
51
- "commandCount": 8,
51
+ "commandCount": 9,
52
52
  "title": "Deck",
53
53
  "summary": "Whole-document state: title, theme, viewport, templates, plus full get/set/patch.",
54
54
  "whenToUse": "Apply a template theme with deck.applyTemplate up front; set the viewport once; use whole-document import/export at persistence boundaries."
@@ -72,11 +72,25 @@
72
72
  "commandCount": 2,
73
73
  "title": "Templates",
74
74
  "summary": "Built-in presentation templates (template_1 … template_8 — same as the UI template picker). templates.catalog lists them; templates.slidesCatalog lists insertable slide slugs by type; deck.applyTemplate sets the deck theme.",
75
- "whenToUse": "FIRST. Pick exactly one template style for the whole deck, apply its theme, then insert slides by slug. Never invent custom slide layouts when a template slide fits."
75
+ "whenToUse": "ALTERNATIVE to styles + layouts, for pixel-perfect branded decks. Pick exactly one template style for the whole deck, apply its theme, then insert slides by slug. Never invent custom slide layouts when a template slide fits."
76
+ },
77
+ {
78
+ "id": "styles",
79
+ "commandCount": 1,
80
+ "title": "Styles",
81
+ "summary": "Curated visual-identity presets (academic, minimal, bold, playful) — each a contrast-safe color palette with named roles + a heading/body font pairing + a type scale. styles.catalog lists them; deck.applyStyle picks ONE and records theme.styleId.",
82
+ "whenToUse": "FIRST, when building a deck from scratch. Pick one style for the whole deck so every layout inherits a coherent, legible look. Use this OR the templates flow — not both."
83
+ },
84
+ {
85
+ "id": "layouts",
86
+ "commandCount": 1,
87
+ "title": "Layouts",
88
+ "summary": "Compositional slide recipes (title, section, closing, bullets, twoColumn, imageText, bigStat, quote, chart, comparison). layouts.catalog lists each layout's content slots and what they expect; slides.createFromLayout builds a themed, positioned slide from a layout id + slots.",
89
+ "whenToUse": "After deck.applyStyle, once per slide. Pick the layout whose composition matches the slide's job and fill its slots with content. The engine themes, positions and auto-fits text to each box, so focus on clear, concise content rather than exact character counts."
76
90
  },
77
91
  {
78
92
  "id": "slides",
79
- "commandCount": 18,
93
+ "commandCount": 19,
80
94
  "title": "Slides",
81
95
  "summary": "Insert slides from built-in templates (slides.insertFromTemplate); read, update, delete, duplicate, move, select; set background, transition and speaker remark.",
82
96
  "whenToUse": "Prefer slides.insertFromTemplate (one call per slide). After insert, use text.setMarkdown on the returned placeholderElementIds/textElementIds. Avoid slides.create for deck building."
@@ -365,6 +379,71 @@
365
379
  ]
366
380
  }
367
381
  },
382
+ {
383
+ "name": "styles.catalog",
384
+ "domain": "styles",
385
+ "payload": "undefined",
386
+ "returns": "PptistStyleSummary[]",
387
+ "doc": {
388
+ "summary": "List the visual-identity style presets (academic, minimal, bold, playful) with their fonts and a color preview.",
389
+ "details": "Read this first when building a deck from scratch. Each preset is a contrast-safe palette + heading/body font pairing + type scale. Pick exactly one whose tone fits the audience, then apply it with deck.applyStyle before adding any slides.",
390
+ "examples": [
391
+ "const styles = controller.styles.catalog() // -> [{ id:'academic', label:'Academic', fonts:{...}, preview:{ background, title, body, accent, featureBackground } }, ...]"
392
+ ],
393
+ "related": [
394
+ "deck.applyStyle",
395
+ "layouts.catalog",
396
+ "slides.createFromLayout"
397
+ ]
398
+ }
399
+ },
400
+ {
401
+ "name": "layouts.catalog",
402
+ "domain": "layouts",
403
+ "payload": "undefined",
404
+ "returns": "PptistLayout[]",
405
+ "doc": {
406
+ "summary": "List the compositional slide layouts and, for each, the content slots you fill (slot name, type, and whether it is required).",
407
+ "details": "Call before each slide. Pick the layout id whose composition matches the slide's purpose (e.g. 'title' for the cover, 'bullets' for a list, 'twoColumn' for compare/contrast, 'bigStat' for a headline metric, 'chart' for data, 'comparison' for a table, 'closing' for the sign-off). Then pass the matching slots to slides.createFromLayout.",
408
+ "examples": [
409
+ "const layouts = controller.layouts.catalog() // -> [{ id:'bullets', label:'Bulleted list', slots:[{ name:'title', type:'text', required:true }, { name:'bullets', type:'bullets', required:true }], ... }, ...]"
410
+ ],
411
+ "related": [
412
+ "slides.createFromLayout",
413
+ "styles.catalog"
414
+ ]
415
+ }
416
+ },
417
+ {
418
+ "name": "deck.applyStyle",
419
+ "domain": "deck",
420
+ "payload": "{ styleId: string }",
421
+ "returns": "PptistApplyStyleResult",
422
+ "optional": true,
423
+ "doc": {
424
+ "summary": "Apply ONE style preset as the deck's visual identity (palette, fonts, type scale). Records theme.styleId so every layout inherits it.",
425
+ "details": "Do this once, up front, before creating slides with slides.createFromLayout. An unknown id falls back to the default style and returns a recoverable warning — read valid ids from styles.catalog.",
426
+ "params": [
427
+ {
428
+ "name": "styleId",
429
+ "type": "string",
430
+ "required": true,
431
+ "description": "A preset id from styles.catalog ('academic' | 'minimal' | 'bold' | 'playful')."
432
+ }
433
+ ],
434
+ "examples": [
435
+ "await controller.deck.applyStyle('academic')"
436
+ ],
437
+ "tips": [
438
+ "Keep one style for the whole deck. Do not hand-pick colors or fonts on top of it — layouts read the preset's role tokens for you."
439
+ ],
440
+ "related": [
441
+ "styles.catalog",
442
+ "layouts.catalog",
443
+ "slides.createFromLayout"
444
+ ]
445
+ }
446
+ },
368
447
  {
369
448
  "name": "deck.setViewport",
370
449
  "domain": "deck",
@@ -458,6 +537,64 @@
458
537
  ]
459
538
  }
460
539
  },
540
+ {
541
+ "name": "slides.createFromLayout",
542
+ "domain": "slides",
543
+ "payload": "{ layoutId: string; slots?: Record<string, unknown>; index?: number; select?: boolean; backgroundMode?: PptistLayoutBackgroundMode }",
544
+ "returns": "PptistCreateFromLayoutResult",
545
+ "optional": true,
546
+ "doc": {
547
+ "summary": "Build + insert a themed slide from a layout id and content slots. The PREFERRED way to add a slide when building from scratch.",
548
+ "details": "The engine positions every element on the canvas, colors it from the active style preset (theme.styleId), and AUTO-FITS each text box's font size (responsive measurement) so text never overflows — you never pick coordinates, sizes, or colors. Author slot content as Markdown/plain text (titles, bullets, body) or structured values (arrays of strings for bullets; { labels, series, legends } for charts; rows for comparison). Returns the new slideId plus the created element ids.",
549
+ "params": [
550
+ {
551
+ "name": "layoutId",
552
+ "type": "string",
553
+ "required": true,
554
+ "description": "Layout id from layouts.catalog (e.g. 'title', 'bullets', 'twoColumn', 'chart')."
555
+ },
556
+ {
557
+ "name": "slots",
558
+ "type": "Record<string, unknown>",
559
+ "required": false,
560
+ "description": "Content slots for the layout (keys + shapes per layouts.catalog)."
561
+ },
562
+ {
563
+ "name": "index",
564
+ "type": "number",
565
+ "required": false,
566
+ "description": "Insert position; appends when omitted."
567
+ },
568
+ {
569
+ "name": "select",
570
+ "type": "boolean",
571
+ "required": false,
572
+ "description": "Select the new slide after insert (default true)."
573
+ },
574
+ {
575
+ "name": "backgroundMode",
576
+ "type": "'auto' | 'feature' | 'plain'",
577
+ "required": false,
578
+ "description": "Force a feature (dark) or plain background; defaults to the layout's own preference."
579
+ }
580
+ ],
581
+ "examples": [
582
+ "await controller.slides.createFromLayout({ layoutId:'title', slots:{ title:'Quarterly Review', subtitle:'Results and outlook', eyebrow:'2026 Q1' } })",
583
+ "await controller.slides.createFromLayout({ layoutId:'bullets', slots:{ title:'Key points', bullets:['First point','Second point','Third point'] } })",
584
+ "await controller.slides.createFromLayout({ layoutId:'chart', slots:{ title:'Revenue by region', chartType:'column', labels:['North','South','East'], series:[[12,28,41]] } })"
585
+ ],
586
+ "tips": [
587
+ "Apply a style once with deck.applyStyle before the first createFromLayout call.",
588
+ "Keep slot copy concise so the auto-fit keeps text at a comfortable size; after each slide, read the auto-screenshot to confirm the result.",
589
+ "Use 'title' for the first slide and 'closing' for the last; 'section' to divide a long deck."
590
+ ],
591
+ "related": [
592
+ "layouts.catalog",
593
+ "deck.applyStyle",
594
+ "text.setMarkdown"
595
+ ]
596
+ }
597
+ },
461
598
  {
462
599
  "name": "slides.insertFromTemplate",
463
600
  "domain": "slides",
@@ -1626,12 +1763,27 @@
1626
1763
  }
1627
1764
  ],
1628
1765
  "guides": [
1766
+ {
1767
+ "id": "styles-layouts-flow",
1768
+ "title": "How to build a deck (styles + layouts)",
1769
+ "summary": "The recommended flow for a fresh deck: pick one style, then build each slide from a layout by filling its content slots.",
1770
+ "body": [
1771
+ "1. Read styles.catalog and pick exactly ONE visual identity (academic, minimal, bold, playful) that fits the audience and topic.",
1772
+ "2. Apply it once: deck.applyStyle({ styleId:'academic' }). This sets the deck theme and records theme.styleId; every layout then inherits its palette, fonts and type scale. Do not hand-pick colors or fonts after this.",
1773
+ "3. Plan the slide flow (e.g. title -> section / bullets / chart / ... -> closing). Keep one todo per slide.",
1774
+ "4. Read layouts.catalog and, for each slide, pick the layout id whose composition matches the slide's job. Note each slot's name, type and whether it is required.",
1775
+ "5. Add the slide with slides.createFromLayout({ layoutId, slots }). Fill slots with Markdown/plain text (titles, bullets, body) or structured values (arrays for bullets; { labels, series } for charts; rows for comparison). The engine themes, positions and auto-fits text to every box — you never set coordinates, colors, or font sizes.",
1776
+ "6. After each slide, look at the auto-screenshot to confirm the result. Text auto-fits its frame so it won't overflow; if the auto-fit made a box shrink uncomfortably small, that slide is overloaded — split it or trim the copy and rebuild.",
1777
+ "7. Use 'title' for the cover and 'closing' for the sign-off; 'section' to divide a long deck.",
1778
+ "8. Only drop to the templates flow (deck.applyTemplate + slides.insertFromTemplate) for pixel-perfect branded decks, or manual slides.create when neither a layout nor a template slide fits."
1779
+ ]
1780
+ },
1629
1781
  {
1630
1782
  "id": "templates-flow",
1631
- "title": "How to build a deck (built-in templates)",
1632
- "summary": "The recommended flow: pick one template style, apply its theme, insert slides by slug, then edit text.",
1783
+ "title": "How to build a deck (alternative: built-in templates)",
1784
+ "summary": "The branded-deck alternative to styles + layouts: pick one template style, apply its theme, insert slides by slug, then edit text.",
1633
1785
  "body": [
1634
- "1. Read templates.catalog and pick exactly ONE template (template_1 … template_8) whose tone fits the audience (e.g. template_1 Crimson landscape for bold keynotes, template_5 Minimal green for crisp lessons).",
1786
+ "1. Read templates.catalog and pick exactly ONE template (template_1 … template_8) whose tone fits the audience (e.g. template_1 Crimson landscape for bold keynotes, template_5 Minimal green for crisp, understated decks).",
1635
1787
  "2. Apply it once: deck.applyTemplate({ templateId:'template_1' }). This sets the deck theme. Do not hand-pick colors or fonts after this.",
1636
1788
  "3. Read templates.slidesCatalog({ templateId }) — slides are grouped by type: cover, contents, transition, content, end. Each entry has a slug and description.",
1637
1789
  "4. For each slide in your outline, call slides.insertFromTemplate({ templateId, slug }) with the slug that best matches (e.g. cover_1 for title, contents_1 for agenda, content_2 for a text+image slide).",
@@ -1793,6 +1945,7 @@
1793
1945
  "PptistAnimationPreset": "export interface PptistAnimationPreset { name: string; value: string }",
1794
1946
  "PptistAnimationPresetGroup": "export interface PptistAnimationPresetGroup { type: string; name: string; children: PptistAnimationPreset[] }",
1795
1947
  "PptistAnimationSequenceStep": "export interface PptistAnimationSequenceStep { index: number; animations: PPTAnimation[]; autoNext: boolean }",
1948
+ "PptistApplyStyleResult": "export interface PptistApplyStyleResult { styleId: string; theme: SlideTheme }",
1796
1949
  "PptistApplyTemplateResult": "export interface PptistApplyTemplateResult { templateId: string; theme: SlideTheme }",
1797
1950
  "PptistAudioElementPatch": "export type PptistAudioElementPatch = Partial<Pick<PPTAudioElement, 'src' | 'ext' | 'autoplay' | 'loop' | 'color' | 'fixedRatio' | 'link' | 'name' | 'lock' | 'groupId'>> & { transform?: PptistAudioTransformPatch }",
1798
1951
  "PptistAudioSourceInput": "export type PptistAudioSourceInput = PptistMediaAssetInput",
@@ -1801,6 +1954,7 @@
1801
1954
  "PptistChartElementPatch": "export interface PptistChartElementPatch { chartType?: ChartType; data?: ChartData; options?: ChartOptions; fill?: PPTChartElement['fill']; outline?: Partial<NonNullable<PPTChartElement['outline']>>; themeColors?: string[]; textColor?: string; lineColor?: string }",
1802
1955
  "PptistCreateAudioInput": "export interface PptistCreateAudioInput extends PptistAudioElementPatch { id?: string; source?: PptistAudioSourceInput; slideId?: string; index?: number; select?: boolean }",
1803
1956
  "PptistCreateChartInput": "export type PptistCreateChartInput = PptistChartElementPatch & Partial<Pick<PPTChartElement, 'id' | 'left' | 'top' | 'width' | 'height' | 'rotate'>> & { slideId?: string; index?: number; select?: boolean }",
1957
+ "PptistCreateFromLayoutResult": "export interface PptistCreateFromLayoutResult { slideId: string; layoutId: string; elementIds: string[]; textElementIds: string[] }",
1804
1958
  "PptistCreateLatexElementInput": "export interface PptistCreateLatexElementInput { slideId?: string; index?: number; element: PptistLatexElementInput; select?: boolean }",
1805
1959
  "PptistCreateLineElementInput": "export interface PptistCreateLineElementInput { slideId?: string; index?: number; element: PptistLineElementInput; select?: boolean }",
1806
1960
  "PptistCreateTableInput": "export type PptistCreateTableInput = PptistTableElementPatch & { id?: string; slideId?: string; index?: number; select?: boolean; element?: Partial<PPTTableElement> }",
@@ -1826,9 +1980,12 @@
1826
1980
  "PptistInsertSlidesResult": "export interface PptistInsertSlidesResult { slides: Slide[]; remap: PptistIdRemap }",
1827
1981
  "PptistJsonPrimitive": "export type PptistJsonPrimitive = string | number | boolean | null",
1828
1982
  "PptistJsonValue": "export type PptistJsonValue = PptistJsonPrimitive | PptistJsonValue[] | { [key: string]: PptistJsonValue }",
1829
- "PptistLatexElementInput": "export type PptistLatexElementInput = PptistLatexElementSizing & Pick<PPTLatexElement, 'latex' | 'path'> & Partial<Pick<PPTLatexElement, 'id' | 'color' | 'strokeWidth' | 'viewBox' | 'fixedRatio' | 'link' | 'name' | 'lock' | 'groupId'>>",
1983
+ "PptistLatexElementInput": "export type PptistLatexElementInput = PptistLatexElementSizing & Pick<PPTLatexElement, 'latex'> & Partial<Pick<PPTLatexElement, 'path' | 'id' | 'color' | 'strokeWidth' | 'viewBox' | 'fixedRatio' | 'link' | 'name' | 'lock' | 'groupId'>>",
1830
1984
  "PptistLatexElementPatch": "export type PptistLatexElementPatch = Partial<PptistLatexElementSizing & Pick<PPTLatexElement, 'latex' | 'path' | 'color' | 'strokeWidth' | 'viewBox' | 'fixedRatio' | 'link' | 'name' | 'lock' | 'groupId'>>",
1831
1985
  "PptistLatexElementSizing": "export interface PptistLatexElementSizing { left?: number; top?: number; width?: number; height?: number; rotate?: number }",
1986
+ "PptistLayout": "export interface PptistLayout { id: string; label: string; summary: string; bestFor: string; feature: boolean; slots: PptistLayoutSlotDef[] }",
1987
+ "PptistLayoutBackgroundMode": "export type PptistLayoutBackgroundMode = 'auto' | 'feature' | 'plain'",
1988
+ "PptistLayoutSlotDef": "export interface PptistLayoutSlotDef { name: string; type: 'text' | 'bullets' | 'image' | 'chart' | 'stats' | 'rows'; required: boolean; description: string }",
1832
1989
  "PptistLineDirectionInput": "export type PptistLineDirectionInput = Broken2LineDirection | 'auto'",
1833
1990
  "PptistLineElementInput": "export type PptistLineElementInput = Partial<Pick<PPTLineElement, 'id' | 'left' | 'top' | 'width' | 'style' | 'color' | 'points' | 'shadow' | 'broken' | 'broken2' | 'broken2Direction' | 'curve' | 'cubic' | 'link' | 'name' | 'lock' | 'groupId'>> & Pick<PPTLineElement, 'start' | 'end'>",
1834
1991
  "PptistLineElementPatch": "export type PptistLineElementPatch = Partial<Pick<PPTLineElement, 'left' | 'top' | 'width' | 'start' | 'end' | 'style' | 'color' | 'points' | 'shadow' | 'broken' | 'broken2' | 'broken2Direction' | 'curve' | 'cubic' | 'link' | 'name' | 'lock' | 'groupId'>>",
@@ -1852,6 +2009,8 @@
1852
2009
  "PptistSlideReference": "export type PptistSlideReference = string | number",
1853
2010
  "PptistSlideThemePatch": "export type PptistSlideThemePatch = Omit<Partial<SlideTheme>, 'outline' | 'shadow'> & { outline?: Partial<SlideTheme['outline']>; shadow?: Partial<SlideTheme['shadow']> }",
1854
2011
  "PptistSlideTransition": "export interface PptistSlideTransition { slideId: string; turningMode?: TurningMode }",
2012
+ "PptistStyleFonts": "export interface PptistStyleFonts { heading: string; body: string }",
2013
+ "PptistStyleSummary": "export interface PptistStyleSummary { id: string; label: string; description: string; fonts: PptistStyleFonts; preview: { background: string; title: string; body: string; accent: string; featureBackground: string } }",
1855
2014
  "PptistTableElementPatch": "export type PptistTableElementPatch = Partial<Omit<PPTTableElement, 'type' | 'id' | 'outline' | 'theme'>> & { outline?: Partial<PPTTableElement['outline']>; theme?: Partial<NonNullable<PPTTableElement['theme']>> }",
1856
2015
  "PptistTemplateSlideEntry": "export interface PptistTemplateSlideEntry { slug: string; type: SlideType; description: string; elementCount: number }",
1857
2016
  "PptistTemplateSlidesCatalog": "export type PptistTemplateSlidesCatalog = Record<SlideType, PptistTemplateSlideEntry[]>",