dsh-office-kit 0.1.0 → 0.3.0

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.
Files changed (198) hide show
  1. package/CAPABILITY.md +147 -68
  2. package/LICENSE.md +21 -21
  3. package/README.md +108 -106
  4. package/assets/skills/excel-live-control/SKILL.md +234 -0
  5. package/assets/skills/excel-live-control/container_tools/live_excel.py +1589 -0
  6. package/assets/skills/excel-live-control/domain_guidance/financial_models.md +86 -0
  7. package/assets/skills/excel-live-control/domain_guidance/healthcare.md +58 -0
  8. package/assets/skills/excel-live-control/domain_guidance/marketing_advertising.md +53 -0
  9. package/assets/skills/excel-live-control/domain_guidance/scientific_research.md +53 -0
  10. package/assets/skills/excel-live-control/references/office-automation.md +207 -0
  11. package/assets/skills/excel-live-control/references/read_only_qna.md +59 -0
  12. package/assets/skills/excel-live-control/style_guidelines.md +87 -0
  13. package/assets/skills/excel-live-control/workflows/create_workflows.md +78 -0
  14. package/assets/skills/excel-live-control/workflows/edit_workflows.md +72 -0
  15. package/assets/skills/office-documents/SKILL.md +90 -77
  16. package/assets/skills/office-documents/examples/end_to_end_smoke_test.md +86 -0
  17. package/assets/skills/office-documents/ooxml/comments.md +40 -0
  18. package/assets/skills/office-documents/ooxml/hyperlinks_and_fields.md +66 -0
  19. package/assets/skills/office-documents/ooxml/rels_and_content_types.md +62 -0
  20. package/assets/skills/office-documents/ooxml/tracked_changes.md +53 -0
  21. package/assets/skills/office-documents/references/docx-structure.md +83 -0
  22. package/assets/skills/office-documents/references/template-elicitation.md +49 -0
  23. package/assets/skills/office-documents/references/writing-quality.md +49 -0
  24. package/assets/skills/office-documents/render_docx.py +92 -0
  25. package/assets/skills/office-documents/scripts/a11y_audit.py +194 -0
  26. package/assets/skills/office-documents/scripts/accept_tracked_changes.py +151 -0
  27. package/assets/skills/office-documents/scripts/add_tracked_replacements.py +148 -0
  28. package/assets/skills/office-documents/scripts/append_blocks.py +108 -0
  29. package/assets/skills/office-documents/scripts/apply_template_styles.py +104 -0
  30. package/assets/skills/office-documents/scripts/captions_and_crossrefs.py +102 -0
  31. package/assets/skills/office-documents/scripts/comments_add.py +136 -0
  32. package/assets/skills/office-documents/scripts/comments_apply_patch.py +114 -0
  33. package/assets/skills/office-documents/scripts/comments_extract.py +85 -0
  34. package/assets/skills/office-documents/scripts/comments_strip.py +74 -0
  35. package/assets/skills/office-documents/scripts/content_controls.py +192 -0
  36. package/assets/skills/office-documents/scripts/core_properties.py +124 -0
  37. package/assets/skills/office-documents/scripts/docx_kit.py +587 -0
  38. package/assets/skills/office-documents/scripts/docx_ooxml_patch.py +225 -0
  39. package/assets/skills/office-documents/scripts/docx_table_to_csv.py +99 -0
  40. package/assets/skills/office-documents/scripts/fields_materialize.py +66 -0
  41. package/assets/skills/office-documents/scripts/fields_report.py +59 -0
  42. package/assets/skills/office-documents/scripts/flatten_ref_fields.py +62 -0
  43. package/assets/skills/office-documents/scripts/footnotes_report.py +77 -0
  44. package/assets/skills/office-documents/scripts/google_docs_title_sanitize.py +96 -0
  45. package/assets/skills/office-documents/scripts/heading_audit.py +81 -0
  46. package/assets/skills/office-documents/scripts/images_audit.py +80 -0
  47. package/assets/skills/office-documents/scripts/insert_note.py +126 -0
  48. package/assets/skills/office-documents/scripts/insert_ref_fields.py +90 -0
  49. package/assets/skills/office-documents/scripts/insert_toc.py +84 -0
  50. package/assets/skills/office-documents/scripts/internal_nav.py +146 -0
  51. package/assets/skills/office-documents/scripts/make_fixtures.py +169 -0
  52. package/assets/skills/office-documents/scripts/merge_docx_append.py +239 -0
  53. package/assets/skills/office-documents/scripts/privacy_scrub.py +131 -0
  54. package/assets/skills/office-documents/scripts/redact_docx.py +113 -0
  55. package/assets/skills/office-documents/scripts/render_and_diff.py +101 -0
  56. package/assets/skills/office-documents/scripts/replace_text.py +154 -0
  57. package/assets/skills/office-documents/scripts/section_audit.py +91 -0
  58. package/assets/skills/office-documents/scripts/set_protection.py +92 -0
  59. package/assets/skills/office-documents/scripts/style_lint.py +111 -0
  60. package/assets/skills/office-documents/scripts/style_normalize.py +103 -0
  61. package/assets/skills/office-documents/scripts/table_geometry.py +167 -0
  62. package/assets/skills/office-documents/scripts/watermark_add.py +48 -0
  63. package/assets/skills/office-documents/scripts/watermark_audit_remove.py +67 -0
  64. package/assets/skills/office-documents/scripts/xlsx_to_docx_table.py +117 -0
  65. package/assets/skills/office-documents/tasks/accessibility_a11y.md +45 -0
  66. package/assets/skills/office-documents/tasks/captions_crossrefs.md +49 -0
  67. package/assets/skills/office-documents/tasks/clean_tracked_changes.md +49 -0
  68. package/assets/skills/office-documents/tasks/comments_manage.md +59 -0
  69. package/assets/skills/office-documents/tasks/compare_diff.md +40 -0
  70. package/assets/skills/office-documents/tasks/create_edit.md +107 -0
  71. package/assets/skills/office-documents/tasks/equations.md +59 -0
  72. package/assets/skills/office-documents/tasks/fields_update.md +44 -0
  73. package/assets/skills/office-documents/tasks/fixtures_edge_cases.md +50 -0
  74. package/assets/skills/office-documents/tasks/footnotes_endnotes.md +38 -0
  75. package/assets/skills/office-documents/tasks/forms_content_controls.md +48 -0
  76. package/assets/skills/office-documents/tasks/headings_numbering.md +55 -0
  77. package/assets/skills/office-documents/tasks/images_figures.md +63 -0
  78. package/assets/skills/office-documents/tasks/multi_doc_merge.md +43 -0
  79. package/assets/skills/office-documents/tasks/navigation_internal_links.md +38 -0
  80. package/assets/skills/office-documents/tasks/privacy_scrub_metadata.md +45 -0
  81. package/assets/skills/office-documents/tasks/protection_restrict_editing.md +41 -0
  82. package/assets/skills/office-documents/tasks/read_review.md +50 -0
  83. package/assets/skills/office-documents/tasks/redaction_anonymization.md +42 -0
  84. package/assets/skills/office-documents/tasks/sections_layout.md +54 -0
  85. package/assets/skills/office-documents/tasks/style_lint_normalize.md +44 -0
  86. package/assets/skills/office-documents/tasks/tables_spreadsheets.md +64 -0
  87. package/assets/skills/office-documents/tasks/templates_style_packs.md +53 -0
  88. package/assets/skills/office-documents/tasks/toc_workflow.md +39 -0
  89. package/assets/skills/office-documents/tasks/verify_render.md +50 -0
  90. package/assets/skills/office-documents/tasks/watermarks_background.md +35 -0
  91. package/assets/skills/office-documents/troubleshooting/libreoffice_headless.md +47 -0
  92. package/assets/skills/office-documents/troubleshooting/run_splitting.md +36 -0
  93. package/assets/skills/office-pdf/SKILL.md +73 -56
  94. package/assets/skills/office-pdf/references/form-fields.md +56 -0
  95. package/assets/skills/office-pdf/references/geometry.md +44 -0
  96. package/assets/skills/office-pdf/references/layout-quality.md +41 -0
  97. package/assets/skills/office-pdf/references/limits.md +58 -0
  98. package/assets/skills/office-pdf/scripts/extract_text.py +172 -0
  99. package/assets/skills/office-pdf/scripts/forms.py +556 -0
  100. package/assets/skills/office-pdf/scripts/metadata.py +161 -0
  101. package/assets/skills/office-pdf/scripts/page_ops.py +198 -0
  102. package/assets/skills/office-pdf/scripts/redact_region.py +347 -0
  103. package/assets/skills/office-pdf/scripts/render_pages.py +207 -0
  104. package/assets/skills/office-pdf/scripts/split_pages.py +155 -0
  105. package/assets/skills/office-pdf/scripts/stamp_overlay.py +199 -0
  106. package/assets/skills/office-pdf/tasks/annotations.md +98 -0
  107. package/assets/skills/office-pdf/tasks/create.md +75 -0
  108. package/assets/skills/office-pdf/tasks/edit-pages.md +71 -0
  109. package/assets/skills/office-pdf/tasks/forms.md +67 -0
  110. package/assets/skills/office-pdf/tasks/read.md +62 -0
  111. package/assets/skills/office-pdf/tasks/redact.md +72 -0
  112. package/assets/skills/office-pdf/tasks/stamp.md +60 -0
  113. package/assets/skills/office-presentations/SKILL.md +141 -87
  114. package/assets/skills/office-presentations/container_tools/add_slides.py +136 -0
  115. package/assets/skills/office-presentations/container_tools/core_properties.py +120 -0
  116. package/assets/skills/office-presentations/container_tools/create_montage.py +126 -0
  117. package/assets/skills/office-presentations/container_tools/inspect_presentation_layout_geometry.py +285 -0
  118. package/assets/skills/office-presentations/container_tools/inspect_presentation_package_integrity.py +157 -0
  119. package/assets/skills/office-presentations/container_tools/native_chart_title_gate.py +144 -0
  120. package/assets/skills/office-presentations/container_tools/native_quantitative_chart_gate.py +199 -0
  121. package/assets/skills/office-presentations/container_tools/native_table_arithmetic_gate.py +212 -0
  122. package/assets/skills/office-presentations/container_tools/ooxml_helpers.py +345 -0
  123. package/assets/skills/office-presentations/container_tools/preview_render.py +375 -0
  124. package/assets/skills/office-presentations/container_tools/render_slides.py +139 -0
  125. package/assets/skills/office-presentations/container_tools/replace_text.py +168 -0
  126. package/assets/skills/office-presentations/container_tools/template_source_fidelity_gate.py +229 -0
  127. package/assets/skills/office-presentations/domain_guidance/finance.md +66 -0
  128. package/assets/skills/office-presentations/recipes/README.md +71 -0
  129. package/assets/skills/office-presentations/recipes/autolayout.md +88 -0
  130. package/assets/skills/office-presentations/recipes/connectors.md +83 -0
  131. package/assets/skills/office-presentations/recipes/images.md +80 -0
  132. package/assets/skills/office-presentations/recipes/master-and-layouts.md +127 -0
  133. package/assets/skills/office-presentations/recipes/native-charts.md +87 -0
  134. package/assets/skills/office-presentations/recipes/rich-text-runs.md +86 -0
  135. package/assets/skills/office-presentations/recipes/speaker-notes.md +65 -0
  136. package/assets/skills/office-presentations/recipes/tables.md +88 -0
  137. package/assets/skills/office-presentations/recipes/textbox-at-coordinate.md +71 -0
  138. package/assets/skills/office-presentations/recipes/theme-tokens.md +87 -0
  139. package/assets/skills/office-presentations/references/authoring-workflow.md +65 -0
  140. package/assets/skills/office-presentations/references/finalization.md +63 -0
  141. package/assets/skills/office-presentations/references/native-bullets.md +78 -0
  142. package/assets/skills/office-presentations/references/native-evidence.md +67 -0
  143. package/assets/skills/office-presentations/references/style-guidelines.md +66 -0
  144. package/assets/skills/office-presentations/references/templates.md +76 -0
  145. package/assets/skills/office-presentations/routing/google_slides.md +45 -0
  146. package/assets/skills/office-presentations/tasks/apply-annotations.md +83 -0
  147. package/assets/skills/office-presentations/tasks/charts-tables-notes.md +79 -0
  148. package/assets/skills/office-presentations/tasks/create-deck.md +106 -0
  149. package/assets/skills/office-presentations/tasks/edit-deck.md +93 -0
  150. package/assets/skills/office-presentations/tasks/inspect-and-verify.md +107 -0
  151. package/assets/skills/office-presentations/tasks/template-following.md +132 -0
  152. package/assets/skills/office-presentations/template_following_scripts/check_template_fidelity.py +176 -0
  153. package/assets/skills/office-presentations/template_following_scripts/inspect_template_deck.py +154 -0
  154. package/assets/skills/office-presentations/template_following_scripts/make_contact_sheet.py +111 -0
  155. package/assets/skills/office-presentations/template_following_scripts/prepare_template_starter_deck.py +239 -0
  156. package/assets/skills/office-presentations/template_following_scripts/validate_template_plan.py +185 -0
  157. package/assets/skills/office-spreadsheets/SKILL.md +105 -101
  158. package/assets/skills/office-spreadsheets/container_tools/add_chart.py +236 -0
  159. package/assets/skills/office-spreadsheets/container_tools/add_image.py +107 -0
  160. package/assets/skills/office-spreadsheets/container_tools/append_rows.py +122 -0
  161. package/assets/skills/office-spreadsheets/container_tools/diff_workbooks.py +306 -0
  162. package/assets/skills/office-spreadsheets/container_tools/inspect_workbook.py +398 -0
  163. package/assets/skills/office-spreadsheets/container_tools/recalc_gate.py +275 -0
  164. package/assets/skills/office-spreadsheets/container_tools/set_cells.py +135 -0
  165. package/assets/skills/office-spreadsheets/container_tools/sheet_ops.py +134 -0
  166. package/assets/skills/office-spreadsheets/container_tools/style_cells.py +133 -0
  167. package/assets/skills/office-spreadsheets/recipes/charts.md +66 -0
  168. package/assets/skills/office-spreadsheets/recipes/conditional-formats.md +69 -0
  169. package/assets/skills/office-spreadsheets/recipes/data-tables.md +58 -0
  170. package/assets/skills/office-spreadsheets/recipes/named-ranges.md +41 -0
  171. package/assets/skills/office-spreadsheets/recipes/number-formats.md +72 -0
  172. package/assets/skills/office-spreadsheets/recipes/sparklines.md +43 -0
  173. package/assets/skills/office-spreadsheets/references/charts.md +63 -0
  174. package/assets/skills/office-spreadsheets/references/domain/financial-models.md +40 -0
  175. package/assets/skills/office-spreadsheets/references/domain/healthcare.md +22 -0
  176. package/assets/skills/office-spreadsheets/references/domain/marketing.md +28 -0
  177. package/assets/skills/office-spreadsheets/references/domain/research.md +22 -0
  178. package/assets/skills/office-spreadsheets/references/formula-patterns.md +78 -0
  179. package/assets/skills/office-spreadsheets/references/style-guidelines.md +69 -0
  180. package/assets/skills/office-spreadsheets/references/workbook-structure.md +60 -0
  181. package/assets/skills/office-spreadsheets/routing/google-sheets.md +36 -0
  182. package/assets/skills/office-spreadsheets/tasks/analyze-workbook.md +37 -0
  183. package/assets/skills/office-spreadsheets/tasks/annotations.md +51 -0
  184. package/assets/skills/office-spreadsheets/tasks/create-workbook.md +66 -0
  185. package/assets/skills/office-spreadsheets/tasks/diff-workbooks.md +38 -0
  186. package/assets/skills/office-spreadsheets/tasks/edit-workbook.md +69 -0
  187. package/assets/skills/office-spreadsheets/tasks/inspect-workbook.md +38 -0
  188. package/assets/skills/office-spreadsheets/tasks/recalc-and-check.md +57 -0
  189. package/assets/skills/shared/annotation-recipes.md +252 -0
  190. package/assets/skills/shared/check_runtime.py +253 -0
  191. package/assets/skills/shared/common-workflow.md +139 -0
  192. package/assets/skills/shared/scripts/ensure_raster_image.py +187 -0
  193. package/dist/client.js +4 -4
  194. package/dist/client.js.map +1 -1
  195. package/dist/index.js +239 -89
  196. package/package.json +146 -149
  197. package/postinstall.mjs +92 -82
  198. package/python/office_cli.py +171 -246
@@ -0,0 +1,63 @@
1
+ # Finalization checklist
2
+
3
+ Run this before `present`. It exists because every item on it has shipped a
4
+ broken deck at least once.
5
+
6
+ ## The file
7
+
8
+ - [ ] Opens: `"<python>" "<cli>" pptx read --input deck.pptx` returns slides.
9
+ - [ ] Package is coherent:
10
+ `"<python>" "<skill>/container_tools/inspect_presentation_package_integrity.py" --input deck.pptx`
11
+ → `passed: true`, no dangling relationships, media and charts present.
12
+ - [ ] Slide count matches the intent; nothing left over from an earlier draft.
13
+ - [ ] Core properties set:
14
+ `"<python>" "<skill>/container_tools/core_properties.py" --input deck.pptx --title "..." --author "..."`
15
+ (an untitled deck shows up as "PowerPoint Presentation" in every file list).
16
+
17
+ ## The content
18
+
19
+ - [ ] Every placeholder is filled or deleted — no "Click to add text".
20
+ - [ ] No default chart title ("Chart Title") survives:
21
+ `"<python>" "<skill>/container_tools/native_chart_title_gate.py" --input deck.pptx`.
22
+ - [ ] Totals are arithmetic:
23
+ `"<python>" "<skill>/container_tools/native_table_arithmetic_gate.py" --input deck.pptx --contracts totals.json`.
24
+ - [ ] Charts have their data in the file (portable mode passes) and categories
25
+ are in a meaningful order.
26
+ - [ ] Numbers in the deck agree with the numbers in the source data, at the
27
+ precision shown.
28
+ - [ ] Speaker notes carry the provenance of the non-obvious numbers.
29
+
30
+ ## The layout
31
+
32
+ - [ ] Geometry gate passes:
33
+ `"<python>" "<skill>/container_tools/inspect_presentation_layout_geometry.py" --input deck.pptx --json-out geometry.json`
34
+ → `passed: true`; review findings read and consciously accepted.
35
+ - [ ] Nothing outside the slide edge, nothing overlapping the footer zone.
36
+ - [ ] Titles are one or two lines; no title ends in a full stop.
37
+ - [ ] Body text is at least 18 pt, captions at least 12 pt.
38
+ - [ ] One idea per slide, one emphasis per paragraph.
39
+
40
+ ## The look
41
+
42
+ - [ ] Rendered at viewing size and actually looked at:
43
+ `"<python>" "<skill>/container_tools/render_slides.py" --input deck.pptx --out-dir preview`
44
+ then `read_image` on each PNG (or on the contact sheet from
45
+ `"<skill>/template_following_scripts/make_contact_sheet.py`).
46
+ - [ ] Text is not clipped, ellipsised or shrunk to illegibility.
47
+ - [ ] Photographs are not stretched; their sources are listed.
48
+ - [ ] Charts read at thumbnail size: the point is visible before any label.
49
+ - [ ] The cover and closing slide both say something.
50
+
51
+ ## Delivery
52
+
53
+ - [ ] The file lives in the user's workspace, not in a temp directory.
54
+ - [ ] Output name is either new (`deck.pptx`) or `<original>-edited.pptx`.
55
+ - [ ] `present` called; the reply states what changed in one sentence and, for
56
+ edits, both paths.
57
+
58
+ ## When rendering is unavailable
59
+
60
+ `render_slides.py --engine draft` draws a geometry preview with PyMuPDF when no
61
+ office suite is installed. It is honest about being approximate: type is drawn
62
+ at declared sizes in a substitute face, and layout chrome is not rendered. Use
63
+ it to catch overlap, overflow and placement — not to judge typography.
@@ -0,0 +1,78 @@
1
+ # Bullets that read as sentences
2
+
3
+ ## The shape of a bullet
4
+
5
+ A bullet is a claim, not a label. Two forms work:
6
+
7
+ - **Claim + consequence**: "Picking is 41% of floor labour hours — travel is the
8
+ cost, not the pick."
9
+ - **Number + meaning**: "12 minutes per order lost to aisle travel."
10
+
11
+ Forms that do not work: a single noun ("Efficiency"), a truncated clause
12
+ ("Picking accounts for…"), a list of three adjectives, or a bullet that restates
13
+ the slide title.
14
+
15
+ ## Length and count
16
+
17
+ - One line, two at the absolute maximum, per bullet on a 16:9 slide.
18
+ - Three to five bullets. Six is a signal to split; eight is a document.
19
+ - No sub-sub-bullets. If a bullet needs a child, the parent was a section.
20
+ - Keep bullets grammatically parallel: all sentences, or all noun phrases.
21
+
22
+ ## Native bullet glyphs
23
+
24
+ Bullets in PowerPoint are paragraph properties, not characters. A bullet
25
+ character typed into the text ("• Picking…") is a bullet that cannot re-indent,
26
+ cannot change level, and looks different from every other bullet in the deck.
27
+
28
+ Set them properly:
29
+
30
+ ```python
31
+ "<python>" - <<'PY'
32
+ from pptx import Presentation
33
+ from pptx.util import Inches, Pt
34
+ from pptx.enum.text import PP_ALIGN
35
+
36
+ prs = Presentation()
37
+ prs.slide_width, prs.slide_height = Inches(13.333), Inches(7.5)
38
+ slide = prs.slides.add_slide(prs.slide_layouts[6])
39
+ box = slide.shapes.add_textbox(Inches(0.9), Inches(1.8), Inches(11.0), Inches(3.6))
40
+ frame = box.text_frame
41
+ frame.word_wrap = True
42
+
43
+ for index, text in enumerate((
44
+ "Picking is 41% of floor labour hours",
45
+ "Aisle travel costs 12 minutes per order",
46
+ "Manual cycle counts stop the line twice a week",
47
+ )):
48
+ paragraph = frame.paragraphs[0] if index == 0 else frame.add_paragraph()
49
+ paragraph.text = text
50
+ paragraph.font.size = Pt(20)
51
+ paragraph.space_after = Pt(12)
52
+ paragraph.level = 0
53
+ paragraph.alignment = PP_ALIGN.LEFT
54
+ # PowerPoint's own bullet: a literal glyph in the paragraph's pPr
55
+ paragraph._pPr.set("marL", str(Inches(0.3)))
56
+ paragraph._pPr.set("indent", str(-Inches(0.3)))
57
+ bu = paragraph._pPr.makeelement(
58
+ "{http://schemas.openxmlformats.org/drawingml/2006/main}buChar", {"char": "•"}
59
+ )
60
+ paragraph._pPr.append(bu)
61
+
62
+ prs.save("bullets.pptx")
63
+ print("bullets:", len(frame.paragraphs))
64
+ PY
65
+ ```
66
+
67
+ The `marL`/`indent` pair is what pulls the second line of a wrapped bullet under
68
+ the text instead of under the glyph — the most common "malformed bullet" defect
69
+ in generated decks.
70
+
71
+ ## Anti-patterns
72
+
73
+ - Bullets as a script: a slide is not a transcript, the speaker notes are.
74
+ - Fake bullets via "– " or "→ " prefixes in the text; they do not indent.
75
+ - Six bullets of equal weight where one is the actual point. Make the point the
76
+ title and the bullets the evidence.
77
+ - Numbered lists where the order does not matter, and bullet lists where it
78
+ does.
@@ -0,0 +1,67 @@
1
+ # Evidence on slides: charts, tables, notes
2
+
3
+ "Evidence" is anything on a slide that claims a fact: a number, a chart, a
4
+ table, a quotation. The rules below keep it checkable.
5
+
6
+ ## Native or it did not happen
7
+
8
+ | Claim | Correct form | Wrong form |
9
+ |---|---|---|
10
+ | Trend over time | Native chart with categories and series | Screenshot of a chart |
11
+ | Exact figures | Native table | Image of a spreadsheet |
12
+ | A single number | A bold run in a sentence | A one-bar chart |
13
+ | A process | Shapes plus connectors | Image of a flowchart |
14
+
15
+ The wrong column has one shared defect: the audience cannot read it at projector
16
+ size and nobody can verify it. Native charts and tables also keep their numbers
17
+ in the package, which is what lets `container_tools/native_quantitative_chart_gate.py`
18
+ and `container_tools/native_table_arithmetic_gate.py` check them.
19
+
20
+ ## Charts
21
+
22
+ - The chart title says what the chart means. The slide title says the conclusion.
23
+ Two titles, two jobs — if they are the same sentence, drop the chart title
24
+ (`chart.has_title = False`) rather than repeat it.
25
+ - Bars start at zero. Lines may start elsewhere only if the axis is labelled.
26
+ - Categories in the order the audience thinks in (Q1..Q4, not alphabetised).
27
+ - Label the few numbers that matter, not every point. Ten data labels is a
28
+ table with rounded corners.
29
+ - One axis. Two y-axes on a slide chart is a way to imply a correlation that may
30
+ not exist.
31
+ - Source and window in the caption: "Driver logs, FY2026, 12 sites".
32
+
33
+ ## Tables
34
+
35
+ - Column order follows the reader's question: what, then how much, then change.
36
+ - Header row is bold and distinct; total row is bold and separated.
37
+ - Numbers right-aligned, one decimal convention per column.
38
+ - A total is arithmetic the reader can check. Fill it from the data, never by
39
+ eye, and let the table arithmetic gate confirm it.
40
+ - Do not put units in every cell; put them in the header.
41
+ - A table with more than about 7 rows belongs in an appendix, with the slide
42
+ stating the conclusion.
43
+
44
+ ## Speaker notes as provenance
45
+
46
+ Notes are where "where did this number come from" lives, so the presenter can
47
+ answer without the slide turning into a footnote.
48
+
49
+ - One note per non-obvious number: source, date range, and any caveat.
50
+ - The sentence you will actually say, in spoken words.
51
+ - No bullet-stacking in notes; notes are prose.
52
+ - Notes are invisible to the render loop — verify them from the file, not the
53
+ PNGs. `container_tools/inspect_presentation_package_integrity.py` counts
54
+ `notesSlides`, and the package dump shows their text.
55
+
56
+ ## Fidelity gates
57
+
58
+ Before presenting a deck that carries numbers:
59
+
60
+ ```bash
61
+ "<python>" container_tools/native_quantitative_chart_gate.py --input deck.pptx --all-slides
62
+ "<python>" container_tools/native_table_arithmetic_gate.py --input deck.pptx --contracts totals.json
63
+ "<python>" container_tools/native_chart_title_gate.py --input deck.pptx
64
+ ```
65
+
66
+ Each prints one JSON object whose `passed` field is the decision. A failing gate
67
+ is not advisory: it means the slide asserts something the file cannot support.
@@ -0,0 +1,66 @@
1
+ # Style guidance
2
+
3
+ ## The type scale
4
+
5
+ Three sizes are enough: title, body, caption. A fourth size is a decision the
6
+ audience has to make, and they will make it wrongly.
7
+
8
+ | Role | Size | Weight | Colour |
9
+ |---|---|---|---|
10
+ | Cover title | 40–48 pt | Bold | Ink |
11
+ | Slide title | 28–36 pt | Bold or semibold | Ink |
12
+ | Body | 18–22 pt | Regular | Ink |
13
+ | Lead-in number | Same as body + bold | Bold | Accent |
14
+ | Caption, source | 12–14 pt | Regular | Muted |
15
+
16
+ Rules that carry the rest:
17
+
18
+ - One typeface family. A second family means "different voice", so use it for
19
+ one thing (a quote, a code line) and nothing else.
20
+ - Bold is emphasis, not decoration: at most one bold phrase per paragraph.
21
+ - All-caps for a 2–4 word label is a design choice; all-caps for a sentence is
22
+ a readability tax.
23
+ - Left-align body text. Centred paragraphs longer than two lines are hard to
24
+ track back to the next line.
25
+
26
+ ## Colour
27
+
28
+ - One ink, one muted, one accent, plus the template's own rule colour. More
29
+ than that and the accent stops meaning "look here".
30
+ - Contrast is a correctness issue: body text on white needs a dark ink
31
+ (roughly luminance ratio 4.5:1), and text over a photograph needs a scrim,
32
+ not luck.
33
+ - Never encode meaning in colour alone — an accent bar showing the direction of
34
+ a metric also needs an arrow or a word.
35
+ - Chart series colours come from the theme; a sixth series colour is a signal
36
+ that the chart has too many series.
37
+
38
+ ## Density
39
+
40
+ - Body blocks stop at about 6 lines of 18 pt on a 16:9 slide before the eye
41
+ stops at the middle.
42
+ - A table on a slide reads at up to about 7 rows × 4 columns. Beyond that it is
43
+ an appendix, and the slide should carry the one row that matters.
44
+ - Whitespace is a layout element, not leftover space: leave at least 0.6 in
45
+ between content blocks and the slide edge.
46
+ - One idea per slide. If the title needs "and", split.
47
+
48
+ ## Cover art direction
49
+
50
+ A cover carries three things: the title, the context line, and the visual that
51
+ sets the tone. Keep them separate roles.
52
+
53
+ - Abstract geometry, a photograph of the actual subject, or a flat colour field
54
+ all work. Clip art of a handshake does not.
55
+ - If the visual is photographic, darken it (a scrim at 40–60% black) under the
56
+ text rather than hoping the text lands on a dark region.
57
+ - If no suitable image exists, use a colour field plus an accent rule. An
58
+ invented diagram pretending to be a photograph is worse than a plain cover.
59
+ - Encode the deck's palette: if the accent is amber, the cover visual should
60
+ contain amber, not a random sunset.
61
+ - Never ship a screenshot of a tool, a UI or another slide as cover art.
62
+
63
+ ## Closing slides
64
+
65
+ The last slide restates the ask in one line and nothing else. "Thank you" alone
66
+ wastes the slot the audience is still looking at while they gather their things.
@@ -0,0 +1,76 @@
1
+ # Working from a supplied template
2
+
3
+ ## Why templates win
4
+
5
+ A template already answers branding, type scale, slide families and chrome. The
6
+ cheapest correct deck puts the user's content into the template's own slides
7
+ and leaves the design alone. Rebuilding the look from a screenshot produces a
8
+ near-miss that reads as "someone remade our deck in a hurry".
9
+
10
+ ## Order of operations
11
+
12
+ 1. **Inspect the template** before judging it:
13
+
14
+ ```bash
15
+ "<python>" "<skill>/template_following_scripts/inspect_template_deck.py" --template brand.pptx --out-dir template-inspect
16
+ ```
17
+
18
+ It writes `template-inspect.ndjson` (per slide: layout, placeholders with
19
+ index, kind, rect and text, background art) and `template-manifest.json`
20
+ (slide size, aspect, layout names, theme fonts, which slides carry
21
+ full-bleed art).
22
+
23
+ 2. **Choose the slide families you need** — cover, section, content, table,
24
+ chart, closing. You want the *fewest* source slides that cover those roles.
25
+
26
+ 3. **Write the frame map** — a JSON plan that names, per output slide, which
27
+ source slide it duplicates and what happens to each element
28
+ (`rewrite`, `rewrite-and-reposition`, `fill-placeholder`, `replace`,
29
+ `delete`, `keep`).
30
+
31
+ 4. **Validate the plan** before building:
32
+
33
+ ```bash
34
+ "<python>" "<skill>/template_following_scripts/validate_template_plan.py" --plan frame-map.json
35
+ ```
36
+
37
+ It rejects unknown actions, out-of-range zones, new primitives without an
38
+ explicit justification, and any attempt to edit a brand or chrome element.
39
+
40
+ 5. **Build the starter deck**, then fill it:
41
+
42
+ ```bash
43
+ "<python>" "<skill>/template_following_scripts/prepare_template_starter_deck.py" --template brand.pptx --plan frame-map.json --out starter.pptx
44
+ ```
45
+
46
+ The starter deck contains only the slides you kept, in your order, with the
47
+ placeholders filled. From there `container_tools/add_slides.py` and the
48
+ recipes extend it.
49
+
50
+ 6. **Check fidelity** against the source:
51
+
52
+ ```bash
53
+ "<python>" "<skill>/template_following_scripts/check_template_fidelity.py" --template brand.pptx --final starter.pptx --plan frame-map.json
54
+ "<python>" "<skill>/container_tools/template_source_fidelity_gate.py" --template brand.pptx --final starter.pptx --requirements fidelity.json
55
+ ```
56
+
57
+ Both print JSON with a `passed` boolean. Leftover placeholders, drifted
58
+ layout rects and opaque panels covering inherited artwork are failures, not
59
+ style opinions.
60
+
61
+ ## Reading a template's own geometry
62
+
63
+ `container_tools/inspect_presentation_layout_geometry.py --input brand.pptx`
64
+ prints every shape's rect in inches, which is what you address when a slide's
65
+ placeholder needs a value that fits its frame.
66
+
67
+ ## Rules
68
+
69
+ - Placeholders keep their index; fill by index rather than adding a textbox on
70
+ top of a placeholder.
71
+ - Never restyle the master to match a screenshot you were given. If the brand
72
+ colours are wrong, ask; guessing produces a deck the brand team rejects.
73
+ - If the template has no suitable family for a slide (say, a two-column
74
+ comparison), say which family you added and why, rather than silently
75
+ inventing a look.
76
+ - Keep the template's slide size. Changing it invalidates every inherited rect.
@@ -0,0 +1,45 @@
1
+ # Handing a deck to Google Slides
2
+
3
+ Google Slides imports `.pptx`, and mostly survives it. What it does not survive
4
+ is worth designing around.
5
+
6
+ ## What converts cleanly
7
+
8
+ - Text frames, bullet levels, speaker notes, slide size and order.
9
+ - Native tables and native charts (data comes across with the chart).
10
+ - Pictures, shapes, solid fills and theme colours.
11
+
12
+ ## What converts badly
13
+
14
+ | Feature | What happens | Do instead |
15
+ |---|---|---|
16
+ | Custom `buChar` glyphs and `marL/indent` | Indent shifts, glyphs fall back | Use plain paragraph levels; check the bullet indent after import |
17
+ | Elbow/curved connectors | Re-anchored or detached | Straight connectors between facing sides |
18
+ | Font not on the reader's machine | Substituted, wider, text reflows | Stick to fonts both environments have, and re-check overflow after import |
19
+ | Text-to-fit-shape autosize | Keeps the shrunk size | Fixed frames with measured text |
20
+ | Animations and transitions | Partially dropped | Do not rely on them for meaning |
21
+ | Embedded workbook charts | Data retained, formatting re-derived | Re-apply axis/label settings in Slides if they matter |
22
+ | Master-level chrome via spTree surgery | Usually kept, occasionally duplicated | Prefer layout-level placeholders |
23
+
24
+ ## The workflow
25
+
26
+ 1. Build the deck as a normal `.pptx` — nothing Slides-specific is needed.
27
+ 2. Render and inspect the PNGs locally first; fix overflow before importing.
28
+ 3. Upload to Drive, open with Google Slides, and check these in order: title
29
+ wrapping, bullet indentation, connector attachment, chart axes, notes.
30
+ 4. If the deck will be edited by other people in Slides, keep shapes distinct
31
+ and named (right-click → rename) so comments and edits are unambiguous.
32
+
33
+ ## Sharing
34
+
35
+ - "Anyone with the link" plus a view-only role is the default for a deck that
36
+ should not be edited in place.
37
+ - Export back to `.pptx` when the user needs a file; Slides' export does not
38
+ preserve everything either, so state which version is authoritative.
39
+ - Comments and suggestions do not travel in the `.pptx` round trip.
40
+
41
+ ## When the user asks for a Slides-native link
42
+
43
+ Deliver the `.pptx` (that is what this pack produces), state the upload path,
44
+ and list the three things to check after import: font substitution, bullet
45
+ indent, chart axes. Claiming a clean conversion without those checks is a guess.
@@ -0,0 +1,83 @@
1
+ # Task: apply an annotation payload
2
+
3
+ The user draws on a rendered slide and sends back an `office-annotations` block.
4
+ Treat it as a change request with coordinates, not as editor state.
5
+
6
+ ## 1. Re-create the geometry the user drew on
7
+
8
+ Annotations refer to the preview the user saw. Render the same way so the
9
+ coordinates mean the same thing:
10
+
11
+ ```bash
12
+ "<python>" "<skill>/container_tools/render_slides.py" --input deck.pptx --out-dir preview
13
+ ```
14
+
15
+ Slide index = `page` in the payload, 1-based. Keep the PNGs — you will compare
16
+ the same slide before and after.
17
+
18
+ ## 2. Resolve each annotation to shapes
19
+
20
+ The region is normalised 0–1 on that slide image. Map it to inches:
21
+
22
+ ```
23
+ left_in = region.left * slide_width_in
24
+ top_in = region.top * slide_height_in
25
+ width_in = region.width * slide_width_in
26
+ height_in = region.height * slide_height_in
27
+ ```
28
+
29
+ Then select candidate shapes whose bounding box overlaps that rect, largest
30
+ overlap first:
31
+
32
+ ```bash
33
+ "<python>" "<skill>/container_tools/inspect_presentation_layout_geometry.py" --input deck.pptx --json-out geometry.json
34
+ ```
35
+
36
+ `geometry.json` lists every shape per slide with `left`, `top`, `width`,
37
+ `height` in inches, plus its text. Two overlapping shapes (a title over a
38
+ background panel) are common: use the annotation's `text` to disambiguate —
39
+ match it against each candidate's text, and prefer an exact or prefix match.
40
+
41
+ ## 3. Decide the smallest edit
42
+
43
+ | Requirement reads like | Do this |
44
+ |---|---|
45
+ | "change this wording" | run-level replace on that shape ([edit-deck](edit-deck.md)) |
46
+ | "move this down" | set `left/top` on that shape only |
47
+ | "make this bigger" | set font size on the runs of that shape, then re-check fit |
48
+ | "this overlaps the table" | resize the shape, or the table, not the whole slide |
49
+ | "recolour" | change the run colour, not the theme |
50
+ | "add a line here" | the rect is a position, not an insertion point: add the shape at that rect, matching nearby type |
51
+
52
+ Never restyle a slide to satisfy a region. The region identifies *what*, the
53
+ requirement says *how much*.
54
+
55
+ ## 4. Apply, write a copy, re-render
56
+
57
+ Mutations go through this pack's tools (`replace_text.py`, `add_slides.py`,
58
+ `core_properties.py`) or a focused `python-pptx` snippet — always to
59
+ `<original>-edited.pptx`.
60
+
61
+ ```bash
62
+ "<python>" "<skill>/container_tools/replace_text.py" --input deck.pptx --find "old" --replace "new" --out deck-edited.pptx
63
+ "<python>" "<skill>/container_tools/render_slides.py" --input deck-edited.pptx --out-dir preview-after
64
+ ```
65
+
66
+ ## 5. Confirm, in words
67
+
68
+ Open the same slide number and check the region now looks right. Report which
69
+ shape you changed, what changed, and the slide number.
70
+
71
+ ## When it cannot be mapped
72
+
73
+ - Empty region, or no shape overlaps it → say that the region covers blank
74
+ space and ask what object was meant.
75
+ - Overlapping candidates that `text` does not disambiguate → name both and ask.
76
+ - The requirement is about something the file has no geometry for (a font that
77
+ is not installed, a transition) → say so plainly.
78
+ - The region covers a chart or table whose values would need to change → state
79
+ that values come from the data, and ask for the corrected figures rather than
80
+ editing the rendered numbers.
81
+
82
+ Never guess silently. "I changed the title on slide 3; the region also touched
83
+ the subtitle, which I left alone" is a good answer. Silence plus a diff is not.
@@ -0,0 +1,79 @@
1
+ # Task: charts, tables and speaker notes
2
+
3
+ Three things that look like one job and share one rule: the numbers must be
4
+ checkable from the file.
5
+
6
+ ## Charts
7
+
8
+ Native, always:
9
+
10
+ ```bash
11
+ "<python>" "<cli>" pptx create --spec with-chart.json --out charted.pptx
12
+ ```
13
+
14
+ or the recipe when you need control of axis, labels or legend:
15
+ [native-charts](../recipes/native-charts.md).
16
+
17
+ Spec keys the builder accepts: `type` (`bar`/`column`/`line`/`pie`, where bar and
18
+ column both render as a clustered column), `title`, `categories`,
19
+ `series[{name, values}]`, `left`, `top`, `width`, `height`.
20
+
21
+ - The chart title says what the chart means; the slide title states the
22
+ conclusion. If both say the same thing, drop the chart title.
23
+ - Categories in the order the reader thinks in.
24
+ - Bars start at zero.
25
+ - A chart that duplicates a table on a neighbouring slide is a review finding,
26
+ not a second view — pick one.
27
+
28
+ Verify:
29
+
30
+ ```bash
31
+ "<python>" "<skill>/container_tools/native_chart_title_gate.py" --input charted.pptx
32
+ "<python>" "<skill>/container_tools/native_quantitative_chart_gate.py" --input charted.pptx --all-slides
33
+ ```
34
+
35
+ ## Tables
36
+
37
+ Spec form (`{"headers": [...], "rows": [[...]]}`) puts the table at the cursor,
38
+ full width; the [tables recipe](../recipes/tables.md) gives you the rect, column
39
+ widths, alignment and the total row styling.
40
+
41
+ Rules: numbers right-aligned, units in the header, total row computed not typed,
42
+ seven rows maximum on a slide.
43
+
44
+ Declare each total so it can be proved:
45
+
46
+ ```bash
47
+ "<python>" "<skill>/container_tools/native_table_arithmetic_gate.py" --input charted.pptx --contracts totals.json
48
+ ```
49
+
50
+ A mismatch exit code is a data bug or a rounding bug. Fix the number or declare
51
+ the rounding; never lower the tolerance to make it pass.
52
+
53
+ ## Speaker notes
54
+
55
+ Notes live beside the slide, not on it:
56
+
57
+ ```bash
58
+ "<python>" "<cli>" pptx read --input deck.pptx # does not print notes
59
+ ```
60
+
61
+ Write them with the [speaker notes recipe](../recipes/speaker-notes.md), then
62
+ confirm they landed:
63
+
64
+ ```bash
65
+ "<python>" "<skill>/container_tools/inspect_presentation_package_integrity.py" --input deck-notes.pptx
66
+ ```
67
+
68
+ `notesSlides` in the part counts should equal the number of slides you wrote
69
+ notes for.
70
+
71
+ Notes carry: the sentence you will say, the provenance of any non-obvious
72
+ number, and the answer to the question the slide invites. Nothing that belongs
73
+ on the slide.
74
+
75
+ ## Putting them together
76
+
77
+ A results slide usually wants: one claim as the title, one chart as the
78
+ evidence, one caption as the source, and the detail in notes. If it needs a
79
+ chart *and* a table, it is two slides — or the table is an appendix.
@@ -0,0 +1,106 @@
1
+ # Task: create a deck
2
+
3
+ ## Inputs to settle first
4
+
5
+ - Audience and setting: live talk, read-on-its-own PDF, or both. A read-only
6
+ deck needs more words; a live deck needs fewer.
7
+ - Length: number of slides or minutes.
8
+ - Brand: a template file, a colour, or nothing (then use the defaults in
9
+ [style-guidelines](../references/style-guidelines.md)).
10
+ - Evidence: numbers, charts, tables and images the user already has. Never
11
+ invent a metric — if a number is needed and missing, say so.
12
+
13
+ ## Route
14
+
15
+ ### Fast path: the spec-driven builder
16
+
17
+ For the ordinary deck (cover, bullets, section, table, chart, image, closing):
18
+
19
+ ```bash
20
+ "<python>" "<cli>" pptx create --spec deck-spec.json --out deck.pptx
21
+ ```
22
+
23
+ `deck-spec.json`:
24
+
25
+ ```json
26
+ {
27
+ "title": "Automation Review",
28
+ "author": "Warehouse Ops",
29
+ "slides": [
30
+ { "layout": "title", "title": "Automation Review", "subtitle": "Warehouse network · FY2026" },
31
+ {
32
+ "layout": "bullets",
33
+ "title": "Where the time goes",
34
+ "bullets": [{ "text": "Picking is 41% of floor labour hours" }, { "text": "Aisle travel costs 12 minutes per order" }]
35
+ },
36
+ { "layout": "section", "title": "What the pilot measured" },
37
+ {
38
+ "layout": "blank",
39
+ "title": "Throughput rose while touches fell",
40
+ "table": {
41
+ "headers": ["Quarter", "Orders", "Touches"],
42
+ "rows": [["Q1", 100, 410], ["Q2", 128, 402], ["Total", 228, 812]]
43
+ }
44
+ },
45
+ {
46
+ "layout": "blank",
47
+ "title": "Orders per quarter",
48
+ "chart": {
49
+ "type": "column",
50
+ "title": "Orders fulfilled per quarter",
51
+ "categories": ["Q1", "Q2"],
52
+ "series": [{ "name": "Orders", "values": [100, 128] }],
53
+ "left": 0.9,
54
+ "top": 1.45,
55
+ "width": 11.5,
56
+ "height": 5.1
57
+ }
58
+ },
59
+ {
60
+ "layout": "bullets",
61
+ "title": "Decision for Thursday",
62
+ "bullets": [{ "text": "Approve two cells in Q1" }]
63
+ }
64
+ ]
65
+ }
66
+ ```
67
+
68
+ Layouts map to `title`, `bullets`, `section`, `title_only`, `blank`. Tables are
69
+ placed at 0.8 in from the left at the running cursor and cannot be positioned —
70
+ put a table on its own slide, or use the [tables recipe](../recipes/tables.md).
71
+
72
+ ### Everything else: build it with the recipes
73
+
74
+ Anything at a coordinate, any crop, any connector, any master change is a
75
+ `python-pptx` snippet:
76
+
77
+ - [textbox at a coordinate](../recipes/textbox-at-coordinate.md)
78
+ - [auto-layout rules](../recipes/autolayout.md)
79
+ - [tables](../recipes/tables.md) · [native charts](../recipes/native-charts.md)
80
+ - [images](../recipes/images.md) · [connectors](../recipes/connectors.md)
81
+ - [rich text runs](../recipes/rich-text-runs.md) · [theme tokens](../recipes/theme-tokens.md)
82
+ - [speaker notes](../recipes/speaker-notes.md) · [masters and layouts](../recipes/master-and-layouts.md)
83
+
84
+ Extending a deck you already built:
85
+
86
+ ```bash
87
+ "<python>" "<skill>/container_tools/add_slides.py" --input deck.pptx --spec extra-slides.json --out deck-2.pptx
88
+ ```
89
+
90
+ ### From a template
91
+
92
+ See [template-following](template-following.md). Do not rebuild a supplied
93
+ template's look by hand.
94
+
95
+ ## Then
96
+
97
+ 1. Set properties: `"<python>" "<skill>/container_tools/core_properties.py" --input deck.pptx --title "..." --author "..."`.
98
+ 2. Verify: [inspect-and-verify](inspect-and-verify.md).
99
+ 3. Deliver with `present`.
100
+
101
+ ## Writing the slides
102
+
103
+ Story first. Write the one-sentence claim for every slide, in order, then fill
104
+ the frames. If a claim needs two sentences, it is two slides. Keep bullets as
105
+ claims ([native-bullets](../references/native-bullets.md)) and evidence native
106
+ ([native-evidence](../references/native-evidence.md)).