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.
- package/CAPABILITY.md +147 -68
- package/README.md +3 -1
- package/assets/skills/excel-live-control/SKILL.md +234 -0
- package/assets/skills/excel-live-control/container_tools/live_excel.py +1589 -0
- package/assets/skills/excel-live-control/domain_guidance/financial_models.md +86 -0
- package/assets/skills/excel-live-control/domain_guidance/healthcare.md +58 -0
- package/assets/skills/excel-live-control/domain_guidance/marketing_advertising.md +53 -0
- package/assets/skills/excel-live-control/domain_guidance/scientific_research.md +53 -0
- package/assets/skills/excel-live-control/references/office-automation.md +207 -0
- package/assets/skills/excel-live-control/references/read_only_qna.md +59 -0
- package/assets/skills/excel-live-control/style_guidelines.md +87 -0
- package/assets/skills/excel-live-control/workflows/create_workflows.md +78 -0
- package/assets/skills/excel-live-control/workflows/edit_workflows.md +72 -0
- package/assets/skills/office-documents/SKILL.md +90 -77
- package/assets/skills/office-documents/examples/end_to_end_smoke_test.md +86 -0
- package/assets/skills/office-documents/ooxml/comments.md +40 -0
- package/assets/skills/office-documents/ooxml/hyperlinks_and_fields.md +66 -0
- package/assets/skills/office-documents/ooxml/rels_and_content_types.md +62 -0
- package/assets/skills/office-documents/ooxml/tracked_changes.md +53 -0
- package/assets/skills/office-documents/references/docx-structure.md +83 -0
- package/assets/skills/office-documents/references/template-elicitation.md +49 -0
- package/assets/skills/office-documents/references/writing-quality.md +49 -0
- package/assets/skills/office-documents/render_docx.py +99 -0
- package/assets/skills/office-documents/scripts/a11y_audit.py +201 -0
- package/assets/skills/office-documents/scripts/accept_tracked_changes.py +158 -0
- package/assets/skills/office-documents/scripts/add_tracked_replacements.py +155 -0
- package/assets/skills/office-documents/scripts/append_blocks.py +115 -0
- package/assets/skills/office-documents/scripts/apply_template_styles.py +111 -0
- package/assets/skills/office-documents/scripts/captions_and_crossrefs.py +109 -0
- package/assets/skills/office-documents/scripts/comments_add.py +143 -0
- package/assets/skills/office-documents/scripts/comments_apply_patch.py +121 -0
- package/assets/skills/office-documents/scripts/comments_extract.py +92 -0
- package/assets/skills/office-documents/scripts/comments_strip.py +81 -0
- package/assets/skills/office-documents/scripts/content_controls.py +199 -0
- package/assets/skills/office-documents/scripts/core_properties.py +131 -0
- package/assets/skills/office-documents/scripts/docx_kit.py +594 -0
- package/assets/skills/office-documents/scripts/docx_ooxml_patch.py +232 -0
- package/assets/skills/office-documents/scripts/docx_table_to_csv.py +106 -0
- package/assets/skills/office-documents/scripts/fields_materialize.py +73 -0
- package/assets/skills/office-documents/scripts/fields_report.py +66 -0
- package/assets/skills/office-documents/scripts/flatten_ref_fields.py +69 -0
- package/assets/skills/office-documents/scripts/footnotes_report.py +84 -0
- package/assets/skills/office-documents/scripts/google_docs_title_sanitize.py +103 -0
- package/assets/skills/office-documents/scripts/heading_audit.py +88 -0
- package/assets/skills/office-documents/scripts/images_audit.py +87 -0
- package/assets/skills/office-documents/scripts/insert_note.py +133 -0
- package/assets/skills/office-documents/scripts/insert_ref_fields.py +97 -0
- package/assets/skills/office-documents/scripts/insert_toc.py +91 -0
- package/assets/skills/office-documents/scripts/internal_nav.py +153 -0
- package/assets/skills/office-documents/scripts/make_fixtures.py +176 -0
- package/assets/skills/office-documents/scripts/merge_docx_append.py +246 -0
- package/assets/skills/office-documents/scripts/privacy_scrub.py +138 -0
- package/assets/skills/office-documents/scripts/redact_docx.py +120 -0
- package/assets/skills/office-documents/scripts/render_and_diff.py +108 -0
- package/assets/skills/office-documents/scripts/replace_text.py +161 -0
- package/assets/skills/office-documents/scripts/section_audit.py +98 -0
- package/assets/skills/office-documents/scripts/set_protection.py +99 -0
- package/assets/skills/office-documents/scripts/style_lint.py +118 -0
- package/assets/skills/office-documents/scripts/style_normalize.py +110 -0
- package/assets/skills/office-documents/scripts/table_geometry.py +174 -0
- package/assets/skills/office-documents/scripts/watermark_add.py +55 -0
- package/assets/skills/office-documents/scripts/watermark_audit_remove.py +74 -0
- package/assets/skills/office-documents/scripts/xlsx_to_docx_table.py +124 -0
- package/assets/skills/office-documents/tasks/accessibility_a11y.md +45 -0
- package/assets/skills/office-documents/tasks/captions_crossrefs.md +49 -0
- package/assets/skills/office-documents/tasks/clean_tracked_changes.md +49 -0
- package/assets/skills/office-documents/tasks/comments_manage.md +59 -0
- package/assets/skills/office-documents/tasks/compare_diff.md +40 -0
- package/assets/skills/office-documents/tasks/create_edit.md +107 -0
- package/assets/skills/office-documents/tasks/equations.md +59 -0
- package/assets/skills/office-documents/tasks/fields_update.md +44 -0
- package/assets/skills/office-documents/tasks/fixtures_edge_cases.md +50 -0
- package/assets/skills/office-documents/tasks/footnotes_endnotes.md +38 -0
- package/assets/skills/office-documents/tasks/forms_content_controls.md +48 -0
- package/assets/skills/office-documents/tasks/headings_numbering.md +55 -0
- package/assets/skills/office-documents/tasks/images_figures.md +63 -0
- package/assets/skills/office-documents/tasks/multi_doc_merge.md +43 -0
- package/assets/skills/office-documents/tasks/navigation_internal_links.md +38 -0
- package/assets/skills/office-documents/tasks/privacy_scrub_metadata.md +45 -0
- package/assets/skills/office-documents/tasks/protection_restrict_editing.md +41 -0
- package/assets/skills/office-documents/tasks/read_review.md +50 -0
- package/assets/skills/office-documents/tasks/redaction_anonymization.md +42 -0
- package/assets/skills/office-documents/tasks/sections_layout.md +54 -0
- package/assets/skills/office-documents/tasks/style_lint_normalize.md +44 -0
- package/assets/skills/office-documents/tasks/tables_spreadsheets.md +64 -0
- package/assets/skills/office-documents/tasks/templates_style_packs.md +53 -0
- package/assets/skills/office-documents/tasks/toc_workflow.md +39 -0
- package/assets/skills/office-documents/tasks/verify_render.md +50 -0
- package/assets/skills/office-documents/tasks/watermarks_background.md +35 -0
- package/assets/skills/office-documents/troubleshooting/libreoffice_headless.md +47 -0
- package/assets/skills/office-documents/troubleshooting/run_splitting.md +36 -0
- package/assets/skills/office-pdf/SKILL.md +73 -56
- package/assets/skills/office-pdf/references/form-fields.md +56 -0
- package/assets/skills/office-pdf/references/geometry.md +44 -0
- package/assets/skills/office-pdf/references/layout-quality.md +41 -0
- package/assets/skills/office-pdf/references/limits.md +58 -0
- package/assets/skills/office-pdf/scripts/extract_text.py +172 -0
- package/assets/skills/office-pdf/scripts/forms.py +556 -0
- package/assets/skills/office-pdf/scripts/metadata.py +161 -0
- package/assets/skills/office-pdf/scripts/page_ops.py +198 -0
- package/assets/skills/office-pdf/scripts/redact_region.py +347 -0
- package/assets/skills/office-pdf/scripts/render_pages.py +207 -0
- package/assets/skills/office-pdf/scripts/split_pages.py +155 -0
- package/assets/skills/office-pdf/scripts/stamp_overlay.py +199 -0
- package/assets/skills/office-pdf/tasks/annotations.md +98 -0
- package/assets/skills/office-pdf/tasks/create.md +75 -0
- package/assets/skills/office-pdf/tasks/edit-pages.md +71 -0
- package/assets/skills/office-pdf/tasks/forms.md +67 -0
- package/assets/skills/office-pdf/tasks/read.md +62 -0
- package/assets/skills/office-pdf/tasks/redact.md +72 -0
- package/assets/skills/office-pdf/tasks/stamp.md +60 -0
- package/assets/skills/office-presentations/SKILL.md +141 -87
- package/assets/skills/office-presentations/container_tools/add_slides.py +143 -0
- package/assets/skills/office-presentations/container_tools/core_properties.py +127 -0
- package/assets/skills/office-presentations/container_tools/create_montage.py +133 -0
- package/assets/skills/office-presentations/container_tools/inspect_presentation_layout_geometry.py +292 -0
- package/assets/skills/office-presentations/container_tools/inspect_presentation_package_integrity.py +164 -0
- package/assets/skills/office-presentations/container_tools/native_chart_title_gate.py +151 -0
- package/assets/skills/office-presentations/container_tools/native_quantitative_chart_gate.py +206 -0
- package/assets/skills/office-presentations/container_tools/native_table_arithmetic_gate.py +219 -0
- package/assets/skills/office-presentations/container_tools/ooxml_helpers.py +352 -0
- package/assets/skills/office-presentations/container_tools/preview_render.py +382 -0
- package/assets/skills/office-presentations/container_tools/render_slides.py +146 -0
- package/assets/skills/office-presentations/container_tools/replace_text.py +175 -0
- package/assets/skills/office-presentations/container_tools/template_source_fidelity_gate.py +236 -0
- package/assets/skills/office-presentations/domain_guidance/finance.md +66 -0
- package/assets/skills/office-presentations/recipes/README.md +71 -0
- package/assets/skills/office-presentations/recipes/autolayout.md +88 -0
- package/assets/skills/office-presentations/recipes/connectors.md +83 -0
- package/assets/skills/office-presentations/recipes/images.md +80 -0
- package/assets/skills/office-presentations/recipes/master-and-layouts.md +127 -0
- package/assets/skills/office-presentations/recipes/native-charts.md +87 -0
- package/assets/skills/office-presentations/recipes/rich-text-runs.md +86 -0
- package/assets/skills/office-presentations/recipes/speaker-notes.md +65 -0
- package/assets/skills/office-presentations/recipes/tables.md +88 -0
- package/assets/skills/office-presentations/recipes/textbox-at-coordinate.md +71 -0
- package/assets/skills/office-presentations/recipes/theme-tokens.md +87 -0
- package/assets/skills/office-presentations/references/authoring-workflow.md +65 -0
- package/assets/skills/office-presentations/references/finalization.md +63 -0
- package/assets/skills/office-presentations/references/native-bullets.md +78 -0
- package/assets/skills/office-presentations/references/native-evidence.md +67 -0
- package/assets/skills/office-presentations/references/style-guidelines.md +66 -0
- package/assets/skills/office-presentations/references/templates.md +76 -0
- package/assets/skills/office-presentations/routing/google_slides.md +45 -0
- package/assets/skills/office-presentations/tasks/apply-annotations.md +83 -0
- package/assets/skills/office-presentations/tasks/charts-tables-notes.md +79 -0
- package/assets/skills/office-presentations/tasks/create-deck.md +106 -0
- package/assets/skills/office-presentations/tasks/edit-deck.md +93 -0
- package/assets/skills/office-presentations/tasks/inspect-and-verify.md +107 -0
- package/assets/skills/office-presentations/tasks/template-following.md +132 -0
- package/assets/skills/office-presentations/template_following_scripts/check_template_fidelity.py +183 -0
- package/assets/skills/office-presentations/template_following_scripts/inspect_template_deck.py +161 -0
- package/assets/skills/office-presentations/template_following_scripts/make_contact_sheet.py +118 -0
- package/assets/skills/office-presentations/template_following_scripts/prepare_template_starter_deck.py +246 -0
- package/assets/skills/office-presentations/template_following_scripts/validate_template_plan.py +192 -0
- package/assets/skills/office-spreadsheets/SKILL.md +105 -101
- package/assets/skills/office-spreadsheets/container_tools/add_chart.py +243 -0
- package/assets/skills/office-spreadsheets/container_tools/add_image.py +114 -0
- package/assets/skills/office-spreadsheets/container_tools/append_rows.py +129 -0
- package/assets/skills/office-spreadsheets/container_tools/diff_workbooks.py +313 -0
- package/assets/skills/office-spreadsheets/container_tools/inspect_workbook.py +405 -0
- package/assets/skills/office-spreadsheets/container_tools/recalc_gate.py +287 -0
- package/assets/skills/office-spreadsheets/container_tools/set_cells.py +142 -0
- package/assets/skills/office-spreadsheets/container_tools/sheet_ops.py +141 -0
- package/assets/skills/office-spreadsheets/container_tools/style_cells.py +140 -0
- package/assets/skills/office-spreadsheets/recipes/charts.md +66 -0
- package/assets/skills/office-spreadsheets/recipes/conditional-formats.md +69 -0
- package/assets/skills/office-spreadsheets/recipes/data-tables.md +58 -0
- package/assets/skills/office-spreadsheets/recipes/named-ranges.md +41 -0
- package/assets/skills/office-spreadsheets/recipes/number-formats.md +72 -0
- package/assets/skills/office-spreadsheets/recipes/sparklines.md +43 -0
- package/assets/skills/office-spreadsheets/references/charts.md +63 -0
- package/assets/skills/office-spreadsheets/references/domain/financial-models.md +40 -0
- package/assets/skills/office-spreadsheets/references/domain/healthcare.md +22 -0
- package/assets/skills/office-spreadsheets/references/domain/marketing.md +28 -0
- package/assets/skills/office-spreadsheets/references/domain/research.md +22 -0
- package/assets/skills/office-spreadsheets/references/formula-patterns.md +78 -0
- package/assets/skills/office-spreadsheets/references/style-guidelines.md +69 -0
- package/assets/skills/office-spreadsheets/references/workbook-structure.md +60 -0
- package/assets/skills/office-spreadsheets/routing/google-sheets.md +36 -0
- package/assets/skills/office-spreadsheets/tasks/analyze-workbook.md +37 -0
- package/assets/skills/office-spreadsheets/tasks/annotations.md +51 -0
- package/assets/skills/office-spreadsheets/tasks/create-workbook.md +66 -0
- package/assets/skills/office-spreadsheets/tasks/diff-workbooks.md +38 -0
- package/assets/skills/office-spreadsheets/tasks/edit-workbook.md +69 -0
- package/assets/skills/office-spreadsheets/tasks/inspect-workbook.md +38 -0
- package/assets/skills/office-spreadsheets/tasks/recalc-and-check.md +57 -0
- package/assets/skills/shared/annotation-recipes.md +252 -0
- package/assets/skills/shared/check_runtime.py +260 -0
- package/assets/skills/shared/common-workflow.md +139 -0
- package/assets/skills/shared/scripts/ensure_raster_image.py +187 -0
- package/dist/client.js +4 -4
- package/dist/client.js.map +1 -1
- package/dist/index.js +246 -89
- package/package.json +1 -1
- package/postinstall.mjs +92 -82
- 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.
|