dsh-office-kit 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/assets/skills/excel-live-control/SKILL.md +119 -152
  2. package/assets/skills/excel-live-control/domain_guidance/financial_models.md +42 -58
  3. package/assets/skills/excel-live-control/domain_guidance/healthcare.md +36 -42
  4. package/assets/skills/excel-live-control/domain_guidance/marketing_advertising.md +33 -34
  5. package/assets/skills/excel-live-control/domain_guidance/scientific_research.md +34 -36
  6. package/assets/skills/excel-live-control/references/office-automation.md +127 -153
  7. package/assets/skills/excel-live-control/references/read_only_qna.md +40 -45
  8. package/assets/skills/excel-live-control/style_guidelines.md +56 -64
  9. package/assets/skills/excel-live-control/workflows/create_workflows.md +40 -47
  10. package/assets/skills/excel-live-control/workflows/edit_workflows.md +37 -45
  11. package/assets/skills/office-documents/SKILL.md +24 -60
  12. package/assets/skills/office-documents/examples/end_to_end_smoke_test.md +5 -5
  13. package/assets/skills/office-documents/ooxml/comments.md +8 -8
  14. package/assets/skills/office-documents/ooxml/hyperlinks_and_fields.md +10 -10
  15. package/assets/skills/office-documents/ooxml/rels_and_content_types.md +7 -7
  16. package/assets/skills/office-documents/ooxml/tracked_changes.md +12 -12
  17. package/assets/skills/office-documents/references/docx-structure.md +11 -13
  18. package/assets/skills/office-documents/references/template-elicitation.md +11 -13
  19. package/assets/skills/office-documents/references/writing-quality.md +20 -20
  20. package/assets/skills/office-documents/scripts/add_tracked_replacements.py +4 -3
  21. package/assets/skills/office-documents/scripts/docx_kit.py +68 -27
  22. package/assets/skills/office-documents/scripts/heading_audit.py +3 -4
  23. package/assets/skills/office-documents/scripts/internal_nav.py +3 -1
  24. package/assets/skills/office-documents/scripts/merge_docx_append.py +104 -0
  25. package/assets/skills/office-documents/scripts/table_geometry.py +13 -3
  26. package/assets/skills/office-documents/scripts/watermark_add.py +6 -5
  27. package/assets/skills/office-documents/scripts/watermark_audit_remove.py +6 -4
  28. package/assets/skills/office-documents/tasks/accessibility_a11y.md +16 -22
  29. package/assets/skills/office-documents/tasks/captions_crossrefs.md +23 -26
  30. package/assets/skills/office-documents/tasks/clean_tracked_changes.md +17 -22
  31. package/assets/skills/office-documents/tasks/comments_manage.md +9 -11
  32. package/assets/skills/office-documents/tasks/compare_diff.md +10 -16
  33. package/assets/skills/office-documents/tasks/create_edit.md +14 -16
  34. package/assets/skills/office-documents/tasks/equations.md +17 -28
  35. package/assets/skills/office-documents/tasks/fields_update.md +14 -16
  36. package/assets/skills/office-documents/tasks/fixtures_edge_cases.md +19 -33
  37. package/assets/skills/office-documents/tasks/footnotes_endnotes.md +12 -14
  38. package/assets/skills/office-documents/tasks/forms_content_controls.md +16 -20
  39. package/assets/skills/office-documents/tasks/headings_numbering.md +17 -22
  40. package/assets/skills/office-documents/tasks/images_figures.md +15 -25
  41. package/assets/skills/office-documents/tasks/multi_doc_merge.md +13 -23
  42. package/assets/skills/office-documents/tasks/navigation_internal_links.md +18 -21
  43. package/assets/skills/office-documents/tasks/privacy_scrub_metadata.md +16 -22
  44. package/assets/skills/office-documents/tasks/protection_restrict_editing.md +19 -21
  45. package/assets/skills/office-documents/tasks/read_review.md +9 -20
  46. package/assets/skills/office-documents/tasks/redaction_anonymization.md +17 -18
  47. package/assets/skills/office-documents/tasks/sections_layout.md +16 -23
  48. package/assets/skills/office-documents/tasks/style_lint_normalize.md +18 -22
  49. package/assets/skills/office-documents/tasks/tables_spreadsheets.md +21 -31
  50. package/assets/skills/office-documents/tasks/templates_style_packs.md +17 -21
  51. package/assets/skills/office-documents/tasks/toc_workflow.md +10 -14
  52. package/assets/skills/office-documents/tasks/verify_render.md +11 -23
  53. package/assets/skills/office-documents/tasks/watermarks_background.md +10 -14
  54. package/assets/skills/office-documents/troubleshooting/libreoffice_headless.md +6 -6
  55. package/assets/skills/office-documents/troubleshooting/run_splitting.md +12 -12
  56. package/assets/skills/office-pdf/SKILL.md +36 -51
  57. package/assets/skills/office-pdf/references/form-fields.md +20 -20
  58. package/assets/skills/office-pdf/references/geometry.md +10 -10
  59. package/assets/skills/office-pdf/references/layout-quality.md +13 -13
  60. package/assets/skills/office-pdf/references/limits.md +12 -56
  61. package/assets/skills/office-pdf/tasks/annotations.md +5 -5
  62. package/assets/skills/office-pdf/tasks/create.md +6 -9
  63. package/assets/skills/office-pdf/tasks/edit-pages.md +14 -14
  64. package/assets/skills/office-pdf/tasks/forms.md +15 -15
  65. package/assets/skills/office-pdf/tasks/read.md +9 -9
  66. package/assets/skills/office-pdf/tasks/redact.md +18 -18
  67. package/assets/skills/office-pdf/tasks/stamp.md +10 -10
  68. package/assets/skills/office-presentations/SKILL.md +71 -91
  69. package/assets/skills/office-presentations/container_tools/preview_render.py +4 -1
  70. package/assets/skills/office-presentations/container_tools/render_slides.py +1 -1
  71. package/assets/skills/office-presentations/domain_guidance/finance.md +16 -16
  72. package/assets/skills/office-presentations/recipes/README.md +24 -35
  73. package/assets/skills/office-presentations/recipes/autolayout.md +12 -13
  74. package/assets/skills/office-presentations/recipes/connectors.md +11 -12
  75. package/assets/skills/office-presentations/recipes/images.md +11 -12
  76. package/assets/skills/office-presentations/recipes/master-and-layouts.md +18 -18
  77. package/assets/skills/office-presentations/recipes/native-charts.md +8 -8
  78. package/assets/skills/office-presentations/recipes/rich-text-runs.md +13 -13
  79. package/assets/skills/office-presentations/recipes/speaker-notes.md +7 -7
  80. package/assets/skills/office-presentations/recipes/tables.md +14 -14
  81. package/assets/skills/office-presentations/recipes/textbox-at-coordinate.md +9 -9
  82. package/assets/skills/office-presentations/recipes/theme-tokens.md +7 -8
  83. package/assets/skills/office-presentations/references/authoring-workflow.md +38 -43
  84. package/assets/skills/office-presentations/references/finalization.md +10 -12
  85. package/assets/skills/office-presentations/references/native-bullets.md +14 -18
  86. package/assets/skills/office-presentations/references/native-evidence.md +18 -32
  87. package/assets/skills/office-presentations/references/style-guidelines.md +27 -32
  88. package/assets/skills/office-presentations/references/templates.md +31 -60
  89. package/assets/skills/office-presentations/routing/google_slides.md +4 -4
  90. package/assets/skills/office-presentations/tasks/apply-annotations.md +17 -17
  91. package/assets/skills/office-presentations/tasks/charts-tables-notes.md +20 -23
  92. package/assets/skills/office-presentations/tasks/create-deck.md +19 -19
  93. package/assets/skills/office-presentations/tasks/edit-deck.md +14 -16
  94. package/assets/skills/office-presentations/tasks/inspect-and-verify.md +31 -34
  95. package/assets/skills/office-presentations/tasks/template-following.md +23 -28
  96. package/assets/skills/office-spreadsheets/SKILL.md +32 -39
  97. package/assets/skills/office-spreadsheets/recipes/charts.md +8 -26
  98. package/assets/skills/office-spreadsheets/recipes/conditional-formats.md +9 -26
  99. package/assets/skills/office-spreadsheets/recipes/data-tables.md +7 -23
  100. package/assets/skills/office-spreadsheets/recipes/named-ranges.md +8 -21
  101. package/assets/skills/office-spreadsheets/recipes/number-formats.md +7 -23
  102. package/assets/skills/office-spreadsheets/recipes/sparklines.md +7 -20
  103. package/assets/skills/office-spreadsheets/references/charts.md +15 -34
  104. package/assets/skills/office-spreadsheets/references/domain/financial-models.md +10 -25
  105. package/assets/skills/office-spreadsheets/references/domain/healthcare.md +8 -19
  106. package/assets/skills/office-spreadsheets/references/domain/marketing.md +8 -22
  107. package/assets/skills/office-spreadsheets/references/domain/research.md +8 -19
  108. package/assets/skills/office-spreadsheets/references/formula-patterns.md +20 -50
  109. package/assets/skills/office-spreadsheets/references/style-guidelines.md +19 -44
  110. package/assets/skills/office-spreadsheets/references/workbook-structure.md +12 -35
  111. package/assets/skills/office-spreadsheets/routing/google-sheets.md +11 -26
  112. package/assets/skills/office-spreadsheets/tasks/analyze-workbook.md +10 -25
  113. package/assets/skills/office-spreadsheets/tasks/annotations.md +12 -30
  114. package/assets/skills/office-spreadsheets/tasks/create-workbook.md +5 -5
  115. package/assets/skills/office-spreadsheets/tasks/diff-workbooks.md +2 -2
  116. package/assets/skills/office-spreadsheets/tasks/edit-workbook.md +5 -5
  117. package/assets/skills/office-spreadsheets/tasks/inspect-workbook.md +9 -9
  118. package/assets/skills/office-spreadsheets/tasks/recalc-and-check.md +10 -30
  119. package/assets/skills/shared/annotation-recipes.md +98 -120
  120. package/assets/skills/shared/common-workflow.md +70 -80
  121. package/dist/index.js +1 -1
  122. package/package.json +1 -1
  123. package/python/office_cli.py +38 -4
@@ -8,24 +8,21 @@ A bullet is a claim, not a label. Two forms work:
8
8
  cost, not the pick."
9
9
  - **Number + meaning**: "12 minutes per order lost to aisle travel."
10
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.
11
+ Forms that fail: a single noun ("Efficiency"), a truncated clause ("Picking
12
+ accounts for…"), three adjectives in a row, or a bullet that restates the slide
13
+ title.
14
14
 
15
15
  ## Length and count
16
16
 
17
17
  - One line, two at the absolute maximum, per bullet on a 16:9 slide.
18
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.
19
+ - No sub-sub-bullets. A bullet needing a child means the parent was a section.
20
20
  - Keep bullets grammatically parallel: all sentences, or all noun phrases.
21
21
 
22
22
  ## Native bullet glyphs
23
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:
24
+ Bullets are paragraph properties, not characters. A typed bullet ("• Picking…")
25
+ cannot re-indent, cannot change level, and looks unlike every other bullet.
29
26
 
30
27
  ```python
31
28
  "<python>" - <<'PY'
@@ -64,15 +61,14 @@ print("bullets:", len(frame.paragraphs))
64
61
  PY
65
62
  ```
66
63
 
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.
64
+ The `marL`/`indent` pair pulls a wrapped bullet's second line under the text
65
+ instead of under the glyph — the most common "malformed bullet" defect in
66
+ generated decks.
70
67
 
71
68
  ## Anti-patterns
72
69
 
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.
70
+ - Bullets as a script: a slide is not a transcript; the speaker notes are.
71
+ - Fake bullets via "– " or "→ " prefixes; they do not indent.
72
+ - Six bullets of equal weight where one is the point. Make the point the title,
73
+ the bullets the evidence.
74
+ - Numbered lists where order does not matter, bullets where it does.
@@ -1,7 +1,7 @@
1
1
  # Evidence on slides: charts, tables, notes
2
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.
3
+ "Evidence" is anything on a slide that claims a fact: a number, a chart, a table,
4
+ a quotation. These rules keep it checkable.
5
5
 
6
6
  ## Native or it did not happen
7
7
 
@@ -12,56 +12,42 @@ table, a quotation. The rules below keep it checkable.
12
12
  | A single number | A bold run in a sentence | A one-bar chart |
13
13
  | A process | Shapes plus connectors | Image of a flowchart |
14
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.
15
+ The wrong column is unreadable at projector size and unverifiable. Native charts
16
+ and tables keep their numbers in the package, which is what lets the
17
+ quantitative-chart and table-arithmetic gates check them
18
+ ([inspect-and-verify](../tasks/inspect-and-verify.md)).
19
19
 
20
20
  ## Charts
21
21
 
22
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.
23
+ If they are the same sentence, drop the chart title (`chart.has_title = False`)
24
+ rather than repeat it.
25
25
  - Bars start at zero. Lines may start elsewhere only if the axis is labelled.
26
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.
27
+ - Label the few numbers that matter, not every point; ten data labels is a table
28
+ with rounded corners.
29
+ - One axis. Two y-axes imply a correlation that may not exist.
31
30
  - Source and window in the caption: "Driver logs, FY2026, 12 sites".
32
31
 
33
32
  ## Tables
34
33
 
35
34
  - 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.
35
+ - Header row bold and distinct; total row bold and separated.
37
36
  - Numbers right-aligned, one decimal convention per column.
38
37
  - A total is arithmetic the reader can check. Fill it from the data, never by
39
38
  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.
39
+ - No units in every cell; units in the header.
40
+ - A table over about 7 rows belongs in an appendix, with the slide stating the
41
+ conclusion.
43
42
 
44
43
  ## Speaker notes as provenance
45
44
 
46
- Notes are where "where did this number come from" lives, so the presenter can
47
- answer without the slide turning into a footnote.
45
+ Notes hold "where did this number come from", so the presenter can answer without
46
+ turning the slide into a footnote.
48
47
 
49
- - One note per non-obvious number: source, date range, and any caveat.
48
+ - One note per non-obvious number: source, date range, any caveat.
50
49
  - The sentence you will actually say, in spoken words.
51
50
  - No bullet-stacking in notes; notes are prose.
52
51
  - Notes are invisible to the render loop — verify them from the file, not the
53
52
  PNGs. `container_tools/inspect_presentation_package_integrity.py` counts
54
53
  `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.
@@ -2,8 +2,8 @@
2
2
 
3
3
  ## The type scale
4
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.
5
+ Three sizes: title, body, caption. A fourth is a decision the audience will make
6
+ wrongly.
7
7
 
8
8
  | Role | Size | Weight | Colour |
9
9
  |---|---|---|---|
@@ -13,54 +13,49 @@ audience has to make, and they will make it wrongly.
13
13
  | Lead-in number | Same as body + bold | Bold | Accent |
14
14
  | Caption, source | 12–14 pt | Regular | Muted |
15
15
 
16
- Rules that carry the rest:
16
+ 44 pt belongs to covers; content titles stay 28–36 pt.
17
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.
18
+ - One typeface family. A second family means "different voice": use it for one
19
+ thing (a quote, a code line) and nothing else.
20
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.
21
+ - All-caps suits a 2–4 word label; in a sentence it is a readability tax.
22
+ - Left-align body text. Centred paragraphs over two lines are hard to track back.
25
23
 
26
24
  ## Colour
27
25
 
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.
26
+ - One ink, one muted, one accent, plus the template's rule colour. More and the
27
+ accent stops meaning "look here".
28
+ - Contrast is a correctness issue: body on white needs dark ink (≈4.5:1), and
29
+ text over a photograph needs a scrim, not luck.
30
+ - Never encode meaning in colour alone: an accent bar also needs an arrow or a
31
+ word.
32
+ - Chart series colours come from the theme; a sixth series colour signals too
33
+ many series.
37
34
 
38
35
  ## Density
39
36
 
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.
37
+ - Body blocks stop at about 6 lines of 18 pt on a 16:9 slide.
38
+ - A slide table reads at about 7 rows × 4 columns. Beyond that it is an appendix,
39
+ and the slide carries the one row that matters.
40
+ - Keep at least 0.6 in between content blocks and the slide edge.
46
41
  - One idea per slide. If the title needs "and", split.
47
42
 
48
43
  ## Cover art direction
49
44
 
50
45
  A cover carries three things: the title, the context line, and the visual that
51
- sets the tone. Keep them separate roles.
46
+ sets the tone. Keep the roles separate.
52
47
 
53
48
  - Abstract geometry, a photograph of the actual subject, or a flat colour field
54
49
  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.
50
+ - Photographic visual: scrim it at 40–60% black under the text rather than
51
+ hoping the text lands on a dark region.
52
+ - No suitable image: colour field plus an accent rule. An invented diagram
53
+ pretending to be a photograph is worse than a plain cover.
54
+ - Encode the deck's palette: an amber accent means an amber-bearing visual, not a
55
+ random sunset.
61
56
  - Never ship a screenshot of a tool, a UI or another slide as cover art.
62
57
 
63
58
  ## Closing slides
64
59
 
65
60
  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.
61
+ wastes the slot the audience looks at while gathering their things.
@@ -1,76 +1,47 @@
1
1
  # Working from a supplied template
2
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".
3
+ A template already answers branding, type scale, slide families and chrome. Put
4
+ the user's content into the template's own slides and leave the design alone;
5
+ rebuilding the look from a screenshot produces a near-miss that reads as "someone
6
+ remade our deck in a hurry".
9
7
 
10
8
  ## Order of operations
11
9
 
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.
10
+ Commands, JSON shapes and gate flags: [tasks/template-following.md](../tasks/template-following.md).
11
+ This file is the reasoning behind that procedure.
12
+
13
+ 1. **Inspect** with `inspect_template_deck.py`. It writes
14
+ `template-inspect.ndjson` (per slide: layout, placeholders with index, kind,
15
+ rect and text, background art) and `template-manifest.json` (slide size,
16
+ aspect, layout names, theme fonts, which slides carry full-bleed art).
17
+ 2. **Choose the families** you need — cover, section, content, table, chart,
18
+ closing. Take the *fewest* source slides that cover those roles.
19
+ 3. **Write the frame map**: a JSON plan naming, per output slide, the source
20
+ slide it duplicates and what happens to each element (`rewrite`,
21
+ `rewrite-and-reposition`, `fill-placeholder`, `replace`, `delete`, `keep`).
22
+ 4. **Validate** with `validate_template_plan.py`: it rejects unknown actions,
23
+ out-of-range zones, new primitives without an explicit justification, and any
24
+ attempt to edit a brand or chrome element.
25
+ 5. **Build** the starter deck with `prepare_template_starter_deck.py`: only the
26
+ slides you kept, in your order, with placeholders filled. Extend it with
27
+ `container_tools/add_slides.py` and the recipes.
28
+ 6. **Check fidelity** with `check_template_fidelity.py` and
29
+ `template_source_fidelity_gate.py`. Leftover placeholders, drifted layout rects
30
+ and opaque panels covering inherited artwork are failures, not style opinions.
60
31
 
61
32
  ## Reading a template's own geometry
62
33
 
63
34
  `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.
35
+ prints every shape's rect in inches — what you address when a placeholder needs a
36
+ value that fits its frame.
66
37
 
67
38
  ## Rules
68
39
 
69
40
  - Placeholders keep their index; fill by index rather than adding a textbox on
70
41
  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.
42
+ - Never restyle the master to match a screenshot. If the brand colours are wrong,
43
+ ask; guessing produces a deck the brand team rejects.
73
44
  - 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.
45
+ comparison), say which family you added and why rather than silently inventing
46
+ a look.
76
47
  - Keep the template's slide size. Changing it invalidates every inherited rect.
@@ -1,6 +1,6 @@
1
1
  # Handing a deck to Google Slides
2
2
 
3
- Google Slides imports `.pptx`, and mostly survives it. What it does not survive
3
+ Google Slides imports `.pptx` and mostly survives it. What it does not survive
4
4
  is worth designing around.
5
5
 
6
6
  ## What converts cleanly
@@ -25,10 +25,10 @@ is worth designing around.
25
25
 
26
26
  1. Build the deck as a normal `.pptx` — nothing Slides-specific is needed.
27
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
28
+ 3. Upload to Drive, open with Google Slides, and check in this order: title
29
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.
30
+ 4. If others will edit the deck in Slides, keep shapes distinct and named
31
+ (right-click → rename) so comments and edits are unambiguous.
32
32
 
33
33
  ## Sharing
34
34
 
@@ -12,8 +12,8 @@ coordinates mean the same thing:
12
12
  "<python>" "<skill>/container_tools/render_slides.py" --input deck.pptx --out-dir preview
13
13
  ```
14
14
 
15
- Slide index = `page` in the payload, 1-based. Keep the PNGs — you will compare
16
- the same slide before and after.
15
+ Slide index = `page` in the payload, 1-based. Keep the PNGs to compare the same
16
+ slide before and after.
17
17
 
18
18
  ## 2. Resolve each annotation to shapes
19
19
 
@@ -26,17 +26,17 @@ width_in = region.width * slide_width_in
26
26
  height_in = region.height * slide_height_in
27
27
  ```
28
28
 
29
- Then select candidate shapes whose bounding box overlaps that rect, largest
30
- overlap first:
29
+ Select candidate shapes whose bounding box overlaps that rect, largest overlap
30
+ first:
31
31
 
32
32
  ```bash
33
33
  "<python>" "<skill>/container_tools/inspect_presentation_layout_geometry.py" --input deck.pptx --json-out geometry.json
34
34
  ```
35
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.
36
+ `geometry.json` lists every shape per slide with `left`, `top`, `width`, `height`
37
+ in inches, plus its text. Overlapping shapes (a title over a background panel)
38
+ are common: use the annotation's `text` to disambiguate — prefer an exact or
39
+ prefix match.
40
40
 
41
41
  ## 3. Decide the smallest edit
42
42
 
@@ -66,18 +66,18 @@ Mutations go through this pack's tools (`replace_text.py`, `add_slides.py`,
66
66
  ## 5. Confirm, in words
67
67
 
68
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.
69
+ shape changed, what changed, and the slide number.
70
70
 
71
71
  ## When it cannot be mapped
72
72
 
73
- - Empty region, or no shape overlaps it → say that the region covers blank
74
- space and ask what object was meant.
73
+ - Empty region, or no shape overlaps it → say the region covers blank space and
74
+ ask what object was meant.
75
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.
76
+ - The requirement is about something the file has no geometry for (an uninstalled
77
+ font, a transition) → say so plainly.
78
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.
79
+ that values come from the data, and ask for corrected figures rather than
80
+ editing rendered numbers.
81
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.
82
+ Never guess silently. "I changed the title on slide 3; the region also touched the
83
+ subtitle, which I left alone" is a good answer. Silence plus a diff is not.
@@ -1,7 +1,6 @@
1
1
  # Task: charts, tables and speaker notes
2
2
 
3
- Three things that look like one job and share one rule: the numbers must be
4
- checkable from the file.
3
+ One rule across all three: the numbers must be checkable from the file.
5
4
 
6
5
  ## Charts
7
6
 
@@ -11,19 +10,18 @@ Native, always:
11
10
  "<python>" "<cli>" pptx create --spec with-chart.json --out charted.pptx
12
11
  ```
13
12
 
14
- or the recipe when you need control of axis, labels or legend:
15
- [native-charts](../recipes/native-charts.md).
13
+ Or the [native-charts recipe](../recipes/native-charts.md) when you need control
14
+ of axis, labels or legend.
16
15
 
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`.
16
+ Spec keys: `type` (`bar`/`column`/`line`/`pie`; bar and column both render as a
17
+ clustered column), `title`, `categories`, `series[{name, values}]`, `left`,
18
+ `top`, `width`, `height`.
20
19
 
21
20
  - The chart title says what the chart means; the slide title states the
22
21
  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.
22
+ - Categories in the order the reader thinks in. Bars start at zero.
23
+ - A chart duplicating a table on a neighbouring slide is a review finding, not a
24
+ second view — pick one.
27
25
 
28
26
  Verify:
29
27
 
@@ -35,8 +33,8 @@ Verify:
35
33
  ## Tables
36
34
 
37
35
  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.
36
+ full width; the [tables recipe](../recipes/tables.md) gives the rect, column
37
+ widths, alignment and total-row styling.
40
38
 
41
39
  Rules: numbers right-aligned, units in the header, total row computed not typed,
42
40
  seven rows maximum on a slide.
@@ -47,8 +45,8 @@ Declare each total so it can be proved:
47
45
  "<python>" "<skill>/container_tools/native_table_arithmetic_gate.py" --input charted.pptx --contracts totals.json
48
46
  ```
49
47
 
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.
48
+ A mismatch is a data bug or a rounding bug. Fix the number or declare the
49
+ rounding; never lower the tolerance to make it pass.
52
50
 
53
51
  ## Speaker notes
54
52
 
@@ -65,15 +63,14 @@ confirm they landed:
65
63
  "<python>" "<skill>/container_tools/inspect_presentation_package_integrity.py" --input deck-notes.pptx
66
64
  ```
67
65
 
68
- `notesSlides` in the part counts should equal the number of slides you wrote
69
- notes for.
66
+ `notesSlides` must equal the number of slides you wrote notes for.
70
67
 
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.
68
+ Notes carry: the sentence you will say, the provenance of any non-obvious number,
69
+ and the answer to the question the slide invites. Nothing that belongs on the
70
+ slide.
74
71
 
75
72
  ## Putting them together
76
73
 
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.
74
+ A results slide wants one claim as the title, one chart as the evidence, one
75
+ caption as the source, and the detail in notes. If it needs a chart *and* a
76
+ table, it is two slides — or the table is an appendix.
@@ -5,10 +5,10 @@
5
5
  - Audience and setting: live talk, read-on-its-own PDF, or both. A read-only
6
6
  deck needs more words; a live deck needs fewer.
7
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.
8
+ - Brand: a template file, a colour, or the defaults in
9
+ [style-guidelines](../references/style-guidelines.md).
10
+ - Evidence: numbers, charts, tables, images the user has. Never invent a metric —
11
+ if a number is needed and missing, say so.
12
12
 
13
13
  ## Route
14
14
 
@@ -65,21 +65,20 @@ For the ordinary deck (cover, bullets, section, table, chart, image, closing):
65
65
  }
66
66
  ```
67
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).
68
+ Layouts: `title`, `bullets`, `section`, `title_only`, `blank`. Tables sit 0.8 in
69
+ from the left at the running cursor and cannot be positioned — give a table its
70
+ own slide, or use the [tables recipe](../recipes/tables.md).
71
71
 
72
72
  ### Everything else: build it with the recipes
73
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)
74
+ Anything at a coordinate, any crop, connector or master change is a `python-pptx`
75
+ snippet: [textbox at a coordinate](../recipes/textbox-at-coordinate.md),
76
+ [auto-layout](../recipes/autolayout.md), [tables](../recipes/tables.md) ·
77
+ [native charts](../recipes/native-charts.md), [images](../recipes/images.md) ·
78
+ [connectors](../recipes/connectors.md), [rich text
79
+ runs](../recipes/rich-text-runs.md) · [theme tokens](../recipes/theme-tokens.md),
80
+ [speaker notes](../recipes/speaker-notes.md) · [masters and
81
+ layouts](../recipes/master-and-layouts.md).
83
82
 
84
83
  Extending a deck you already built:
85
84
 
@@ -100,7 +99,8 @@ template's look by hand.
100
99
 
101
100
  ## Writing the slides
102
101
 
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
102
+ Story first: the one-sentence claim for every slide, in order, then fill the
103
+ frames (loop in [authoring-workflow](../references/authoring-workflow.md)). A
104
+ claim needing two sentences is two slides. Bullets are claims
105
+ ([native-bullets](../references/native-bullets.md)); evidence is native
106
106
  ([native-evidence](../references/native-evidence.md)).
@@ -2,7 +2,7 @@
2
2
 
3
3
  Editing is mutation, and mutation lives in this pack's tools, not in the helper
4
4
  CLI: `container_tools/replace_text.py`, `add_slides.py`, `core_properties.py`,
5
- plus the recipes for everything structural.
5
+ plus the recipes for anything structural.
6
6
 
7
7
  **Never write over the original.** Every tool defaults to
8
8
  `<original>-edited.pptx`; keep that default unless the user names a path.
@@ -14,9 +14,8 @@ plus the recipes for everything structural.
14
14
  "<python>" "<skill>/container_tools/inspect_presentation_layout_geometry.py" --input deck.pptx
15
15
  ```
16
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.
17
+ `pptx read` gives titles, text, tables and chart data per slide; the geometry
18
+ gate gives every shape's rect in inches, to decide whether a new block fits.
20
19
 
21
20
  ## 2. Text changes: run-level replace
22
21
 
@@ -41,11 +40,11 @@ Batch form:
41
40
  "<python>" "<skill>/container_tools/replace_text.py" --input deck.pptx --spec replacements.json
42
41
  ```
43
42
 
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.
43
+ A pattern matches **inside a single run** only. Text PowerPoint split for
44
+ formatting ("**Q4** 2025") will not match "Q4 2025" and the report lists it under
45
+ `unmatched`. When a pattern cannot match, edit that paragraph with a run-level
46
+ snippet ([rich text runs](../recipes/rich-text-runs.md)) rather than widening the
47
+ match.
49
48
 
50
49
  Exit code 1 means a pattern matched nothing; the file is still written, so read
51
50
  `unmatched` before delivering.
@@ -56,10 +55,9 @@ Exit code 1 means a pattern matched nothing; the file is still written, so read
56
55
  "<python>" "<skill>/container_tools/add_slides.py" --input deck.pptx --spec extra-slides.json
57
56
  ```
58
57
 
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.
58
+ The spec uses the same slide object as `pptx create` (`layout`, `title`,
59
+ `subtitle`, `bullets`, `table`, `chart`, `image`). Outside that vocabulary, add
60
+ the slide with `add_slides.py`, then place content with a recipe.
63
61
 
64
62
  ## 4. Metadata
65
63
 
@@ -72,7 +70,7 @@ recipe.
72
70
 
73
71
  | Change | Route |
74
72
  |---|---|
75
- | Move or resize a shape | recipe: set `.left/.top/.width/.height` on the shape from `slide.shapes` |
73
+ | Move or resize a shape | set `.left/.top/.width/.height` from `slide.shapes` |
76
74
  | Restyle a family | [masters and layouts](../recipes/master-and-layouts.md) |
77
75
  | Add notes | [speaker notes](../recipes/speaker-notes.md) |
78
76
  | Replace a chart's data | [native charts](../recipes/native-charts.md) — edit the series, do not paste a picture |
@@ -89,5 +87,5 @@ relational:
89
87
  "<python>" "<skill>/container_tools/render_slides.py" --input deck-edited.pptx --out-dir preview
90
88
  ```
91
89
 
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.
90
+ Then look at the changed pages. A replacement that pushes a title onto a third
91
+ line is a layout change, not a text change.