dsh-office-kit 0.2.0 → 0.3.1

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 (197) hide show
  1. package/CAPABILITY.md +147 -68
  2. package/README.md +3 -1
  3. package/assets/skills/excel-live-control/SKILL.md +234 -0
  4. package/assets/skills/excel-live-control/container_tools/live_excel.py +1589 -0
  5. package/assets/skills/excel-live-control/domain_guidance/financial_models.md +86 -0
  6. package/assets/skills/excel-live-control/domain_guidance/healthcare.md +58 -0
  7. package/assets/skills/excel-live-control/domain_guidance/marketing_advertising.md +53 -0
  8. package/assets/skills/excel-live-control/domain_guidance/scientific_research.md +53 -0
  9. package/assets/skills/excel-live-control/references/office-automation.md +207 -0
  10. package/assets/skills/excel-live-control/references/read_only_qna.md +59 -0
  11. package/assets/skills/excel-live-control/style_guidelines.md +87 -0
  12. package/assets/skills/excel-live-control/workflows/create_workflows.md +78 -0
  13. package/assets/skills/excel-live-control/workflows/edit_workflows.md +72 -0
  14. package/assets/skills/office-documents/SKILL.md +90 -77
  15. package/assets/skills/office-documents/examples/end_to_end_smoke_test.md +86 -0
  16. package/assets/skills/office-documents/ooxml/comments.md +40 -0
  17. package/assets/skills/office-documents/ooxml/hyperlinks_and_fields.md +66 -0
  18. package/assets/skills/office-documents/ooxml/rels_and_content_types.md +62 -0
  19. package/assets/skills/office-documents/ooxml/tracked_changes.md +53 -0
  20. package/assets/skills/office-documents/references/docx-structure.md +83 -0
  21. package/assets/skills/office-documents/references/template-elicitation.md +49 -0
  22. package/assets/skills/office-documents/references/writing-quality.md +49 -0
  23. package/assets/skills/office-documents/render_docx.py +99 -0
  24. package/assets/skills/office-documents/scripts/a11y_audit.py +201 -0
  25. package/assets/skills/office-documents/scripts/accept_tracked_changes.py +158 -0
  26. package/assets/skills/office-documents/scripts/add_tracked_replacements.py +155 -0
  27. package/assets/skills/office-documents/scripts/append_blocks.py +115 -0
  28. package/assets/skills/office-documents/scripts/apply_template_styles.py +111 -0
  29. package/assets/skills/office-documents/scripts/captions_and_crossrefs.py +109 -0
  30. package/assets/skills/office-documents/scripts/comments_add.py +143 -0
  31. package/assets/skills/office-documents/scripts/comments_apply_patch.py +121 -0
  32. package/assets/skills/office-documents/scripts/comments_extract.py +92 -0
  33. package/assets/skills/office-documents/scripts/comments_strip.py +81 -0
  34. package/assets/skills/office-documents/scripts/content_controls.py +199 -0
  35. package/assets/skills/office-documents/scripts/core_properties.py +131 -0
  36. package/assets/skills/office-documents/scripts/docx_kit.py +594 -0
  37. package/assets/skills/office-documents/scripts/docx_ooxml_patch.py +232 -0
  38. package/assets/skills/office-documents/scripts/docx_table_to_csv.py +106 -0
  39. package/assets/skills/office-documents/scripts/fields_materialize.py +73 -0
  40. package/assets/skills/office-documents/scripts/fields_report.py +66 -0
  41. package/assets/skills/office-documents/scripts/flatten_ref_fields.py +69 -0
  42. package/assets/skills/office-documents/scripts/footnotes_report.py +84 -0
  43. package/assets/skills/office-documents/scripts/google_docs_title_sanitize.py +103 -0
  44. package/assets/skills/office-documents/scripts/heading_audit.py +88 -0
  45. package/assets/skills/office-documents/scripts/images_audit.py +87 -0
  46. package/assets/skills/office-documents/scripts/insert_note.py +133 -0
  47. package/assets/skills/office-documents/scripts/insert_ref_fields.py +97 -0
  48. package/assets/skills/office-documents/scripts/insert_toc.py +91 -0
  49. package/assets/skills/office-documents/scripts/internal_nav.py +153 -0
  50. package/assets/skills/office-documents/scripts/make_fixtures.py +176 -0
  51. package/assets/skills/office-documents/scripts/merge_docx_append.py +246 -0
  52. package/assets/skills/office-documents/scripts/privacy_scrub.py +138 -0
  53. package/assets/skills/office-documents/scripts/redact_docx.py +120 -0
  54. package/assets/skills/office-documents/scripts/render_and_diff.py +108 -0
  55. package/assets/skills/office-documents/scripts/replace_text.py +161 -0
  56. package/assets/skills/office-documents/scripts/section_audit.py +98 -0
  57. package/assets/skills/office-documents/scripts/set_protection.py +99 -0
  58. package/assets/skills/office-documents/scripts/style_lint.py +118 -0
  59. package/assets/skills/office-documents/scripts/style_normalize.py +110 -0
  60. package/assets/skills/office-documents/scripts/table_geometry.py +174 -0
  61. package/assets/skills/office-documents/scripts/watermark_add.py +55 -0
  62. package/assets/skills/office-documents/scripts/watermark_audit_remove.py +74 -0
  63. package/assets/skills/office-documents/scripts/xlsx_to_docx_table.py +124 -0
  64. package/assets/skills/office-documents/tasks/accessibility_a11y.md +45 -0
  65. package/assets/skills/office-documents/tasks/captions_crossrefs.md +49 -0
  66. package/assets/skills/office-documents/tasks/clean_tracked_changes.md +49 -0
  67. package/assets/skills/office-documents/tasks/comments_manage.md +59 -0
  68. package/assets/skills/office-documents/tasks/compare_diff.md +40 -0
  69. package/assets/skills/office-documents/tasks/create_edit.md +107 -0
  70. package/assets/skills/office-documents/tasks/equations.md +59 -0
  71. package/assets/skills/office-documents/tasks/fields_update.md +44 -0
  72. package/assets/skills/office-documents/tasks/fixtures_edge_cases.md +50 -0
  73. package/assets/skills/office-documents/tasks/footnotes_endnotes.md +38 -0
  74. package/assets/skills/office-documents/tasks/forms_content_controls.md +48 -0
  75. package/assets/skills/office-documents/tasks/headings_numbering.md +55 -0
  76. package/assets/skills/office-documents/tasks/images_figures.md +63 -0
  77. package/assets/skills/office-documents/tasks/multi_doc_merge.md +43 -0
  78. package/assets/skills/office-documents/tasks/navigation_internal_links.md +38 -0
  79. package/assets/skills/office-documents/tasks/privacy_scrub_metadata.md +45 -0
  80. package/assets/skills/office-documents/tasks/protection_restrict_editing.md +41 -0
  81. package/assets/skills/office-documents/tasks/read_review.md +50 -0
  82. package/assets/skills/office-documents/tasks/redaction_anonymization.md +42 -0
  83. package/assets/skills/office-documents/tasks/sections_layout.md +54 -0
  84. package/assets/skills/office-documents/tasks/style_lint_normalize.md +44 -0
  85. package/assets/skills/office-documents/tasks/tables_spreadsheets.md +64 -0
  86. package/assets/skills/office-documents/tasks/templates_style_packs.md +53 -0
  87. package/assets/skills/office-documents/tasks/toc_workflow.md +39 -0
  88. package/assets/skills/office-documents/tasks/verify_render.md +50 -0
  89. package/assets/skills/office-documents/tasks/watermarks_background.md +35 -0
  90. package/assets/skills/office-documents/troubleshooting/libreoffice_headless.md +47 -0
  91. package/assets/skills/office-documents/troubleshooting/run_splitting.md +36 -0
  92. package/assets/skills/office-pdf/SKILL.md +73 -56
  93. package/assets/skills/office-pdf/references/form-fields.md +56 -0
  94. package/assets/skills/office-pdf/references/geometry.md +44 -0
  95. package/assets/skills/office-pdf/references/layout-quality.md +41 -0
  96. package/assets/skills/office-pdf/references/limits.md +58 -0
  97. package/assets/skills/office-pdf/scripts/extract_text.py +172 -0
  98. package/assets/skills/office-pdf/scripts/forms.py +556 -0
  99. package/assets/skills/office-pdf/scripts/metadata.py +161 -0
  100. package/assets/skills/office-pdf/scripts/page_ops.py +198 -0
  101. package/assets/skills/office-pdf/scripts/redact_region.py +347 -0
  102. package/assets/skills/office-pdf/scripts/render_pages.py +207 -0
  103. package/assets/skills/office-pdf/scripts/split_pages.py +155 -0
  104. package/assets/skills/office-pdf/scripts/stamp_overlay.py +199 -0
  105. package/assets/skills/office-pdf/tasks/annotations.md +98 -0
  106. package/assets/skills/office-pdf/tasks/create.md +75 -0
  107. package/assets/skills/office-pdf/tasks/edit-pages.md +71 -0
  108. package/assets/skills/office-pdf/tasks/forms.md +67 -0
  109. package/assets/skills/office-pdf/tasks/read.md +62 -0
  110. package/assets/skills/office-pdf/tasks/redact.md +72 -0
  111. package/assets/skills/office-pdf/tasks/stamp.md +60 -0
  112. package/assets/skills/office-presentations/SKILL.md +141 -87
  113. package/assets/skills/office-presentations/container_tools/add_slides.py +143 -0
  114. package/assets/skills/office-presentations/container_tools/core_properties.py +127 -0
  115. package/assets/skills/office-presentations/container_tools/create_montage.py +133 -0
  116. package/assets/skills/office-presentations/container_tools/inspect_presentation_layout_geometry.py +292 -0
  117. package/assets/skills/office-presentations/container_tools/inspect_presentation_package_integrity.py +164 -0
  118. package/assets/skills/office-presentations/container_tools/native_chart_title_gate.py +151 -0
  119. package/assets/skills/office-presentations/container_tools/native_quantitative_chart_gate.py +206 -0
  120. package/assets/skills/office-presentations/container_tools/native_table_arithmetic_gate.py +219 -0
  121. package/assets/skills/office-presentations/container_tools/ooxml_helpers.py +352 -0
  122. package/assets/skills/office-presentations/container_tools/preview_render.py +382 -0
  123. package/assets/skills/office-presentations/container_tools/render_slides.py +146 -0
  124. package/assets/skills/office-presentations/container_tools/replace_text.py +175 -0
  125. package/assets/skills/office-presentations/container_tools/template_source_fidelity_gate.py +236 -0
  126. package/assets/skills/office-presentations/domain_guidance/finance.md +66 -0
  127. package/assets/skills/office-presentations/recipes/README.md +71 -0
  128. package/assets/skills/office-presentations/recipes/autolayout.md +88 -0
  129. package/assets/skills/office-presentations/recipes/connectors.md +83 -0
  130. package/assets/skills/office-presentations/recipes/images.md +80 -0
  131. package/assets/skills/office-presentations/recipes/master-and-layouts.md +127 -0
  132. package/assets/skills/office-presentations/recipes/native-charts.md +87 -0
  133. package/assets/skills/office-presentations/recipes/rich-text-runs.md +86 -0
  134. package/assets/skills/office-presentations/recipes/speaker-notes.md +65 -0
  135. package/assets/skills/office-presentations/recipes/tables.md +88 -0
  136. package/assets/skills/office-presentations/recipes/textbox-at-coordinate.md +71 -0
  137. package/assets/skills/office-presentations/recipes/theme-tokens.md +87 -0
  138. package/assets/skills/office-presentations/references/authoring-workflow.md +65 -0
  139. package/assets/skills/office-presentations/references/finalization.md +63 -0
  140. package/assets/skills/office-presentations/references/native-bullets.md +78 -0
  141. package/assets/skills/office-presentations/references/native-evidence.md +67 -0
  142. package/assets/skills/office-presentations/references/style-guidelines.md +66 -0
  143. package/assets/skills/office-presentations/references/templates.md +76 -0
  144. package/assets/skills/office-presentations/routing/google_slides.md +45 -0
  145. package/assets/skills/office-presentations/tasks/apply-annotations.md +83 -0
  146. package/assets/skills/office-presentations/tasks/charts-tables-notes.md +79 -0
  147. package/assets/skills/office-presentations/tasks/create-deck.md +106 -0
  148. package/assets/skills/office-presentations/tasks/edit-deck.md +93 -0
  149. package/assets/skills/office-presentations/tasks/inspect-and-verify.md +107 -0
  150. package/assets/skills/office-presentations/tasks/template-following.md +132 -0
  151. package/assets/skills/office-presentations/template_following_scripts/check_template_fidelity.py +183 -0
  152. package/assets/skills/office-presentations/template_following_scripts/inspect_template_deck.py +161 -0
  153. package/assets/skills/office-presentations/template_following_scripts/make_contact_sheet.py +118 -0
  154. package/assets/skills/office-presentations/template_following_scripts/prepare_template_starter_deck.py +246 -0
  155. package/assets/skills/office-presentations/template_following_scripts/validate_template_plan.py +192 -0
  156. package/assets/skills/office-spreadsheets/SKILL.md +105 -101
  157. package/assets/skills/office-spreadsheets/container_tools/add_chart.py +243 -0
  158. package/assets/skills/office-spreadsheets/container_tools/add_image.py +114 -0
  159. package/assets/skills/office-spreadsheets/container_tools/append_rows.py +129 -0
  160. package/assets/skills/office-spreadsheets/container_tools/diff_workbooks.py +313 -0
  161. package/assets/skills/office-spreadsheets/container_tools/inspect_workbook.py +405 -0
  162. package/assets/skills/office-spreadsheets/container_tools/recalc_gate.py +287 -0
  163. package/assets/skills/office-spreadsheets/container_tools/set_cells.py +142 -0
  164. package/assets/skills/office-spreadsheets/container_tools/sheet_ops.py +141 -0
  165. package/assets/skills/office-spreadsheets/container_tools/style_cells.py +140 -0
  166. package/assets/skills/office-spreadsheets/recipes/charts.md +66 -0
  167. package/assets/skills/office-spreadsheets/recipes/conditional-formats.md +69 -0
  168. package/assets/skills/office-spreadsheets/recipes/data-tables.md +58 -0
  169. package/assets/skills/office-spreadsheets/recipes/named-ranges.md +41 -0
  170. package/assets/skills/office-spreadsheets/recipes/number-formats.md +72 -0
  171. package/assets/skills/office-spreadsheets/recipes/sparklines.md +43 -0
  172. package/assets/skills/office-spreadsheets/references/charts.md +63 -0
  173. package/assets/skills/office-spreadsheets/references/domain/financial-models.md +40 -0
  174. package/assets/skills/office-spreadsheets/references/domain/healthcare.md +22 -0
  175. package/assets/skills/office-spreadsheets/references/domain/marketing.md +28 -0
  176. package/assets/skills/office-spreadsheets/references/domain/research.md +22 -0
  177. package/assets/skills/office-spreadsheets/references/formula-patterns.md +78 -0
  178. package/assets/skills/office-spreadsheets/references/style-guidelines.md +69 -0
  179. package/assets/skills/office-spreadsheets/references/workbook-structure.md +60 -0
  180. package/assets/skills/office-spreadsheets/routing/google-sheets.md +36 -0
  181. package/assets/skills/office-spreadsheets/tasks/analyze-workbook.md +37 -0
  182. package/assets/skills/office-spreadsheets/tasks/annotations.md +51 -0
  183. package/assets/skills/office-spreadsheets/tasks/create-workbook.md +66 -0
  184. package/assets/skills/office-spreadsheets/tasks/diff-workbooks.md +38 -0
  185. package/assets/skills/office-spreadsheets/tasks/edit-workbook.md +69 -0
  186. package/assets/skills/office-spreadsheets/tasks/inspect-workbook.md +38 -0
  187. package/assets/skills/office-spreadsheets/tasks/recalc-and-check.md +57 -0
  188. package/assets/skills/shared/annotation-recipes.md +252 -0
  189. package/assets/skills/shared/check_runtime.py +260 -0
  190. package/assets/skills/shared/common-workflow.md +139 -0
  191. package/assets/skills/shared/scripts/ensure_raster_image.py +187 -0
  192. package/dist/client.js +4 -4
  193. package/dist/client.js.map +1 -1
  194. package/dist/index.js +246 -89
  195. package/package.json +1 -1
  196. package/postinstall.mjs +92 -82
  197. package/python/office_cli.py +213 -254
@@ -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)).
@@ -0,0 +1,93 @@
1
+ # Task: edit an existing deck
2
+
3
+ Editing is mutation, and mutation lives in this pack's tools, not in the helper
4
+ CLI: `container_tools/replace_text.py`, `add_slides.py`, `core_properties.py`,
5
+ plus the recipes for everything structural.
6
+
7
+ **Never write over the original.** Every tool defaults to
8
+ `<original>-edited.pptx`; keep that default unless the user names a path.
9
+
10
+ ## 1. Understand the file first
11
+
12
+ ```bash
13
+ "<python>" "<cli>" pptx read --input deck.pptx
14
+ "<python>" "<skill>/container_tools/inspect_presentation_layout_geometry.py" --input deck.pptx
15
+ ```
16
+
17
+ `pptx read` gives titles, text, tables and chart data per slide. The geometry
18
+ gate gives every shape's rect in inches, which is what you need to decide
19
+ whether a new block fits.
20
+
21
+ ## 2. Text changes: run-level replace
22
+
23
+ ```bash
24
+ "<python>" "<skill>/container_tools/replace_text.py" --input deck.pptx \
25
+ --find "Q4 2025" --replace "Q4 2026" --out deck-edited.pptx
26
+ ```
27
+
28
+ Batch form:
29
+
30
+ ```json
31
+ {
32
+ "replacements": [
33
+ { "find": "Q4 2025", "replace": "Q4 2026" },
34
+ { "find": "€", "replace": "EUR ", "match_case": true },
35
+ { "find": "draft", "replace": "final", "slide": 7 }
36
+ ]
37
+ }
38
+ ```
39
+
40
+ ```bash
41
+ "<python>" "<skill>/container_tools/replace_text.py" --input deck.pptx --spec replacements.json
42
+ ```
43
+
44
+ Semantics that matter: a pattern only matches **inside a single run**. Text that
45
+ PowerPoint split for formatting ("**Q4** 2025") will not match "Q4 2025" and the
46
+ report lists it under `unmatched`. When a pattern cannot match, that is the
47
+ signal to edit that paragraph with a run-level snippet
48
+ ([rich text runs](../recipes/rich-text-runs.md)) rather than widening the match.
49
+
50
+ Exit code 1 means a pattern matched nothing; the file is still written, so read
51
+ `unmatched` before delivering.
52
+
53
+ ## 3. Adding slides
54
+
55
+ ```bash
56
+ "<python>" "<skill>/container_tools/add_slides.py" --input deck.pptx --spec extra-slides.json
57
+ ```
58
+
59
+ The spec is the same slide object as `pptx create` (`layout`, `title`,
60
+ `subtitle`, `bullets`, `table`, `chart`, `image`). For anything outside that
61
+ vocabulary, add the slide with `add_slides.py` and then place content with a
62
+ recipe.
63
+
64
+ ## 4. Metadata
65
+
66
+ ```bash
67
+ "<python>" "<skill>/container_tools/core_properties.py" --input deck.pptx \
68
+ --title "Automation Review" --author "Warehouse Ops" --subject "FY2026 capital plan"
69
+ ```
70
+
71
+ ## 5. Structural changes
72
+
73
+ | Change | Route |
74
+ |---|---|
75
+ | Move or resize a shape | recipe: set `.left/.top/.width/.height` on the shape from `slide.shapes` |
76
+ | Restyle a family | [masters and layouts](../recipes/master-and-layouts.md) |
77
+ | Add notes | [speaker notes](../recipes/speaker-notes.md) |
78
+ | Replace a chart's data | [native charts](../recipes/native-charts.md) — edit the series, do not paste a picture |
79
+ | Fix a table's total | [tables](../recipes/tables.md), then the arithmetic gate |
80
+ | Delete a slide | `prs.slides._sldIdLst.remove(...)` after `prs.part.drop_rel(rId)` |
81
+
82
+ ## 6. Verify before delivering
83
+
84
+ Deleting or inserting a slide commonly breaks nothing visible and everything
85
+ relational:
86
+
87
+ ```bash
88
+ "<python>" "<skill>/container_tools/inspect_presentation_package_integrity.py" --input deck-edited.pptx
89
+ "<python>" "<skill>/container_tools/render_slides.py" --input deck-edited.pptx --out-dir preview
90
+ ```
91
+
92
+ Then look at the changed pages. A text replacement that pushes a title onto a
93
+ third line is a layout change, not a text change.
@@ -0,0 +1,107 @@
1
+ # Task: inspect and verify a deck
2
+
3
+ Verification is reading the artefact back and looking at it. The tools below
4
+ print one JSON object each; `passed` is the decision.
5
+
6
+ ## 1. What is in the file
7
+
8
+ ```bash
9
+ "<python>" "<cli>" pptx read --input deck.pptx
10
+ ```
11
+
12
+ Per slide: title, all text, tables as rows, charts with type/title/categories/
13
+ series, image count. This is the cheapest sanity check that the content you
14
+ meant to write is the content that was written.
15
+
16
+ ## 2. Is the package coherent
17
+
18
+ ```bash
19
+ "<python>" "<skill>/container_tools/inspect_presentation_package_integrity.py" --input deck.pptx
20
+ ```
21
+
22
+ Checks required parts, slide/master presence, dangling relationships, XML that
23
+ does not parse, slide count drift and duplicate parts, then reports part counts
24
+ (`slides`, `layouts`, `masters`, `charts`, `notesSlides`, `media`,
25
+ `embeddings`). A chart with an `embeddings` count of zero has lost its data.
26
+
27
+ ## 3. Does the layout hold
28
+
29
+ ```bash
30
+ "<python>" "<skill>/container_tools/inspect_presentation_layout_geometry.py" --input deck.pptx --json-out geometry.json
31
+ ```
32
+
33
+ `fail` findings (block a delivery): shape outside the slide, degenerate size,
34
+ text that cannot fit its frame, table outside the slide, chart or table covered
35
+ by another shape. `review` findings (read them, then decide): text overlap,
36
+ empty placeholder, title under 28 pt, body under 14 pt, heading ending in a full
37
+ stop, connector across text, a chart duplicating a table's labels.
38
+
39
+ Add `--strict` to make review findings blocking for a formal deck.
40
+
41
+ ## 4. Are the numbers real
42
+
43
+ ```bash
44
+ "<python>" "<skill>/container_tools/native_chart_title_gate.py" --input deck.pptx
45
+ "<python>" "<skill>/container_tools/native_quantitative_chart_gate.py" --input deck.pptx --all-slides
46
+ "<python>" "<skill>/container_tools/native_table_arithmetic_gate.py" --input deck.pptx --contracts totals.json
47
+ ```
48
+
49
+ - Chart titles: fails on leftover "Chart Title" or an empty title, unless the
50
+ chart is explicitly suppressed.
51
+ - Quantitative charts: every declared chart must be a real chart part with a
52
+ readable series, and in the default `portable` mode must carry its embedded
53
+ workbook.
54
+ - Table arithmetic: only declared totals are enforced, compared against the
55
+ displayed rounding; columns whose header is not additive (unit price, ratio,
56
+ percent) are skipped rather than summed wrongly.
57
+
58
+ `totals.json` names the contract explicitly:
59
+
60
+ ```json
61
+ { "contracts": [{ "slide": 4, "table": 1, "total_row": 6, "columns": [1, 2] }] }
62
+ ```
63
+
64
+ ## 5. Rendering and looking
65
+
66
+ ```bash
67
+ "<python>" "<skill>/container_tools/render_slides.py" --input deck.pptx --out-dir preview
68
+ ```
69
+
70
+ Writes `slide-NN.png` plus `render.json`. Then `read_image` every PNG — an
71
+ unlooked-at render is not verification.
72
+
73
+ To see the whole deck at once:
74
+
75
+ ```bash
76
+ "<python>" "<skill>/template_following_scripts/make_contact_sheet.py" --dir preview --out sheet.png --columns 3
77
+ ```
78
+
79
+ or `"<skill>/container_tools/create_montage.py` with an explicit file list.
80
+
81
+ Look for: clipped text, overlapping blocks, a title that reflowed, a chart whose
82
+ point is invisible at thumbnail size, a photograph stretched, a slide with no
83
+ title.
84
+
85
+ ## 6. When nothing can render
86
+
87
+ With no Microsoft Office, WPS Office, or LibreOffice installed
88
+ (`office_status` → `renderers.kingsoft_wps` / `microsoft_office` / `libreoffice`),
89
+ `render_slides.py` falls back to `--engine draft`, a PyMuPDF geometry preview. It
90
+ shows placement, overflow and overlap — not typography or theme chrome. Say so
91
+ when reporting: "verified as a geometry preview" is honest, "looks great" from an
92
+ approximate render is not.
93
+
94
+ If even the preview cannot run, the delivery is unverified: report the failing
95
+ command, the file's slide count from `pptx read`, and the gate results, and tell
96
+ the user which renderer to install for a visual check.
97
+
98
+ ## Gate summary
99
+
100
+ | Gate | Command | Blocking |
101
+ |---|---|---|
102
+ | Package integrity | `inspect_presentation_package_integrity.py` | yes |
103
+ | Layout geometry | `inspect_presentation_layout_geometry.py` | `fail` always, `review` with `--strict` |
104
+ | Chart titles | `native_chart_title_gate.py` | yes |
105
+ | Chart data | `native_quantitative_chart_gate.py` | yes for declared slides |
106
+ | Table arithmetic | `native_table_arithmetic_gate.py` | yes for declared contracts |
107
+ | Template fidelity | `template_source_fidelity_gate.py` | yes when requirements are supplied |
@@ -0,0 +1,132 @@
1
+ # Task: follow a supplied template
2
+
3
+ Use this when the user hands over a `.pptx` and says "use our template" or "match
4
+ this deck". The design is already decided; your job is to put content into its
5
+ own slides.
6
+
7
+ ## 1. Inspect
8
+
9
+ ```bash
10
+ "<python>" "<skill>/template_following_scripts/inspect_template_deck.py" --template brand.pptx --out-dir template-inspect
11
+ ```
12
+
13
+ Outputs:
14
+
15
+ - `template-inspect.ndjson` — one JSON line per slide: layout name, layout
16
+ placeholders, slide placeholders (index, kind, rect in inches, text), shape
17
+ counts, text excerpt, whether the slide has full-bleed background art.
18
+ - `template-manifest.json` — slide size, aspect ratio, layout names, theme font
19
+ names, and `backgroundArtSlides`.
20
+
21
+ Read `backgroundArtSlides` before adding anything: those slides already carry
22
+ artwork, so a new opaque panel will cover it.
23
+
24
+ ## 2. Plan
25
+
26
+ Write `frame-map.json`:
27
+
28
+ ```json
29
+ {
30
+ "template": "brand.pptx",
31
+ "newPrimitives": { "allowed": false, "justification": "" },
32
+ "outputSlides": [
33
+ {
34
+ "slide": 1,
35
+ "mode": "duplicate-slide",
36
+ "sourceSlide": 1,
37
+ "elements": [
38
+ {
39
+ "elementId": "title",
40
+ "action": "fill-placeholder",
41
+ "target": { "placeholder": "title", "text": "Automation Review" }
42
+ },
43
+ {
44
+ "elementId": "subtitle",
45
+ "action": "fill-placeholder",
46
+ "target": { "placeholder": "subtitle", "text": "Warehouse network · FY2026" }
47
+ }
48
+ ]
49
+ },
50
+ {
51
+ "slide": 2,
52
+ "mode": "duplicate-slide",
53
+ "sourceSlide": 3,
54
+ "elements": [
55
+ {
56
+ "elementId": "title",
57
+ "action": "rewrite",
58
+ "target": { "placeholder": "title", "text": "Throughput rose while touches fell" }
59
+ }
60
+ ]
61
+ }
62
+ ]
63
+ }
64
+ ```
65
+
66
+ Allowed actions: `rewrite`, `rewrite-and-reposition`, `replace`, `delete`,
67
+ `keep`, `fill-placeholder`. `target.zone` is `[x, y, w, h]` in 0–1 slide
68
+ fractions, used with `rewrite-and-reposition`. Elements whose `role` is
69
+ `brand`, `logo`, `bumper`, `divider`, `section`, `chrome` or `footer` must stay
70
+ `keep` — they are the template.
71
+
72
+ Adding new shapes is opt-in: set `newPrimitives.allowed` and write a
73
+ justification. The validator rejects shapes added without it, because "one extra
74
+ box" is how a branded deck stops matching brand.
75
+
76
+ ## 3. Validate
77
+
78
+ ```bash
79
+ "<python>" "<skill>/template_following_scripts/validate_template_plan.py" --plan frame-map.json
80
+ ```
81
+
82
+ Rejects: unknown action, preserved role edited, zone outside 0–1, non-sequential
83
+ slide numbers, missing justification for new primitives, and duplicate source
84
+ slides (a warning — it means two output slides share artwork, usually fine for a
85
+ repeated section divider, usually a copy-paste mistake otherwise).
86
+
87
+ ## 4. Build
88
+
89
+ ```bash
90
+ "<python>" "<skill>/template_following_scripts/prepare_template_starter_deck.py" --template brand.pptx --plan frame-map.json --out starter.pptx
91
+ ```
92
+
93
+ The starter deck keeps only the mapped source slides, in plan order, and applies
94
+ the actions. It refuses duplicate source slides (it reuses slides rather than
95
+ cloning parts). The report lists applied actions and any placeholder left empty.
96
+
97
+ From here, extend with `container_tools/add_slides.py` or the recipes when the
98
+ template has no family for a slide you need.
99
+
100
+ ## 5. Check fidelity
101
+
102
+ ```bash
103
+ "<python>" "<skill>/template_following_scripts/check_template_fidelity.py" --template brand.pptx --final starter.pptx --plan frame-map.json
104
+ "<python>" "<skill>/container_tools/template_source_fidelity_gate.py" --template brand.pptx --final starter.pptx --requirements fidelity.json
105
+ ```
106
+
107
+ `fidelity.json`:
108
+
109
+ ```json
110
+ {
111
+ "reference_slide_indices": [1, 3],
112
+ "mapping": { "1": 1, "2": 3 },
113
+ "minimum_coverage_ratio": 1.0,
114
+ "require_exact_dimensions": true,
115
+ "require_placeholder_geometry": true,
116
+ "require_photographic_background": false,
117
+ "geometry_tolerance_emu": 9144
118
+ }
119
+ ```
120
+
121
+ Both print `passed`. With no requirements, the fidelity gate is a deliberate
122
+ no-op pass — pass a requirements file or you have not checked anything.
123
+
124
+ ## 6. Look at it
125
+
126
+ ```bash
127
+ "<python>" "<skill>/container_tools/render_slides.py" --input starter.pptx --out-dir starter-preview
128
+ ```
129
+
130
+ Compare against the source slides. A filled placeholder that overflows, a title
131
+ in the wrong family, or a panel over the corner logo is exactly what this step
132
+ exists to catch.