dsh-office-kit 0.4.2 → 0.4.3
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/assets/skills/excel-live-control/SKILL.md +119 -152
- package/assets/skills/excel-live-control/domain_guidance/financial_models.md +42 -58
- package/assets/skills/excel-live-control/domain_guidance/healthcare.md +36 -42
- package/assets/skills/excel-live-control/domain_guidance/marketing_advertising.md +33 -34
- package/assets/skills/excel-live-control/domain_guidance/scientific_research.md +34 -36
- package/assets/skills/excel-live-control/references/office-automation.md +127 -153
- package/assets/skills/excel-live-control/references/read_only_qna.md +40 -45
- package/assets/skills/excel-live-control/style_guidelines.md +56 -64
- package/assets/skills/excel-live-control/workflows/create_workflows.md +40 -47
- package/assets/skills/excel-live-control/workflows/edit_workflows.md +37 -45
- package/assets/skills/office-documents/SKILL.md +24 -60
- package/assets/skills/office-documents/examples/end_to_end_smoke_test.md +5 -5
- package/assets/skills/office-documents/ooxml/comments.md +8 -8
- package/assets/skills/office-documents/ooxml/hyperlinks_and_fields.md +10 -10
- package/assets/skills/office-documents/ooxml/rels_and_content_types.md +7 -7
- package/assets/skills/office-documents/ooxml/tracked_changes.md +12 -12
- package/assets/skills/office-documents/references/docx-structure.md +11 -13
- package/assets/skills/office-documents/references/template-elicitation.md +11 -13
- package/assets/skills/office-documents/references/writing-quality.md +20 -20
- package/assets/skills/office-documents/tasks/accessibility_a11y.md +16 -22
- package/assets/skills/office-documents/tasks/captions_crossrefs.md +23 -26
- package/assets/skills/office-documents/tasks/clean_tracked_changes.md +17 -22
- package/assets/skills/office-documents/tasks/comments_manage.md +9 -11
- package/assets/skills/office-documents/tasks/compare_diff.md +10 -16
- package/assets/skills/office-documents/tasks/create_edit.md +14 -16
- package/assets/skills/office-documents/tasks/equations.md +17 -28
- package/assets/skills/office-documents/tasks/fields_update.md +14 -16
- package/assets/skills/office-documents/tasks/fixtures_edge_cases.md +19 -33
- package/assets/skills/office-documents/tasks/footnotes_endnotes.md +12 -14
- package/assets/skills/office-documents/tasks/forms_content_controls.md +16 -20
- package/assets/skills/office-documents/tasks/headings_numbering.md +17 -22
- package/assets/skills/office-documents/tasks/images_figures.md +15 -25
- package/assets/skills/office-documents/tasks/multi_doc_merge.md +13 -23
- package/assets/skills/office-documents/tasks/navigation_internal_links.md +18 -21
- package/assets/skills/office-documents/tasks/privacy_scrub_metadata.md +16 -22
- package/assets/skills/office-documents/tasks/protection_restrict_editing.md +19 -21
- package/assets/skills/office-documents/tasks/read_review.md +9 -20
- package/assets/skills/office-documents/tasks/redaction_anonymization.md +17 -18
- package/assets/skills/office-documents/tasks/sections_layout.md +16 -23
- package/assets/skills/office-documents/tasks/style_lint_normalize.md +18 -22
- package/assets/skills/office-documents/tasks/tables_spreadsheets.md +21 -31
- package/assets/skills/office-documents/tasks/templates_style_packs.md +17 -21
- package/assets/skills/office-documents/tasks/toc_workflow.md +10 -14
- package/assets/skills/office-documents/tasks/verify_render.md +11 -23
- package/assets/skills/office-documents/tasks/watermarks_background.md +11 -15
- package/assets/skills/office-documents/troubleshooting/libreoffice_headless.md +6 -6
- package/assets/skills/office-documents/troubleshooting/run_splitting.md +12 -12
- package/assets/skills/office-pdf/SKILL.md +36 -51
- package/assets/skills/office-pdf/references/form-fields.md +20 -20
- package/assets/skills/office-pdf/references/geometry.md +10 -10
- package/assets/skills/office-pdf/references/layout-quality.md +13 -13
- package/assets/skills/office-pdf/references/limits.md +12 -56
- package/assets/skills/office-pdf/tasks/annotations.md +5 -5
- package/assets/skills/office-pdf/tasks/create.md +6 -9
- package/assets/skills/office-pdf/tasks/edit-pages.md +14 -14
- package/assets/skills/office-pdf/tasks/forms.md +15 -15
- package/assets/skills/office-pdf/tasks/read.md +9 -9
- package/assets/skills/office-pdf/tasks/redact.md +18 -18
- package/assets/skills/office-pdf/tasks/stamp.md +10 -10
- package/assets/skills/office-presentations/SKILL.md +71 -91
- package/assets/skills/office-presentations/container_tools/render_slides.py +1 -1
- package/assets/skills/office-presentations/domain_guidance/finance.md +16 -16
- package/assets/skills/office-presentations/recipes/README.md +24 -35
- package/assets/skills/office-presentations/recipes/autolayout.md +12 -13
- package/assets/skills/office-presentations/recipes/connectors.md +11 -12
- package/assets/skills/office-presentations/recipes/images.md +11 -12
- package/assets/skills/office-presentations/recipes/master-and-layouts.md +18 -18
- package/assets/skills/office-presentations/recipes/native-charts.md +8 -8
- package/assets/skills/office-presentations/recipes/rich-text-runs.md +13 -13
- package/assets/skills/office-presentations/recipes/speaker-notes.md +7 -7
- package/assets/skills/office-presentations/recipes/tables.md +14 -14
- package/assets/skills/office-presentations/recipes/textbox-at-coordinate.md +9 -9
- package/assets/skills/office-presentations/recipes/theme-tokens.md +7 -8
- package/assets/skills/office-presentations/references/authoring-workflow.md +38 -43
- package/assets/skills/office-presentations/references/finalization.md +10 -12
- package/assets/skills/office-presentations/references/native-bullets.md +14 -18
- package/assets/skills/office-presentations/references/native-evidence.md +18 -32
- package/assets/skills/office-presentations/references/style-guidelines.md +27 -32
- package/assets/skills/office-presentations/references/templates.md +31 -60
- package/assets/skills/office-presentations/routing/google_slides.md +4 -4
- package/assets/skills/office-presentations/tasks/apply-annotations.md +17 -17
- package/assets/skills/office-presentations/tasks/charts-tables-notes.md +20 -23
- package/assets/skills/office-presentations/tasks/create-deck.md +19 -19
- package/assets/skills/office-presentations/tasks/edit-deck.md +14 -16
- package/assets/skills/office-presentations/tasks/inspect-and-verify.md +31 -34
- package/assets/skills/office-presentations/tasks/template-following.md +23 -28
- package/assets/skills/office-spreadsheets/SKILL.md +32 -39
- package/assets/skills/office-spreadsheets/recipes/charts.md +8 -26
- package/assets/skills/office-spreadsheets/recipes/conditional-formats.md +9 -26
- package/assets/skills/office-spreadsheets/recipes/data-tables.md +7 -23
- package/assets/skills/office-spreadsheets/recipes/named-ranges.md +8 -21
- package/assets/skills/office-spreadsheets/recipes/number-formats.md +7 -23
- package/assets/skills/office-spreadsheets/recipes/sparklines.md +7 -20
- package/assets/skills/office-spreadsheets/references/charts.md +15 -34
- package/assets/skills/office-spreadsheets/references/domain/financial-models.md +10 -25
- package/assets/skills/office-spreadsheets/references/domain/healthcare.md +8 -19
- package/assets/skills/office-spreadsheets/references/domain/marketing.md +8 -22
- package/assets/skills/office-spreadsheets/references/domain/research.md +8 -19
- package/assets/skills/office-spreadsheets/references/formula-patterns.md +20 -50
- package/assets/skills/office-spreadsheets/references/style-guidelines.md +19 -44
- package/assets/skills/office-spreadsheets/references/workbook-structure.md +12 -35
- package/assets/skills/office-spreadsheets/routing/google-sheets.md +11 -26
- package/assets/skills/office-spreadsheets/tasks/analyze-workbook.md +10 -25
- package/assets/skills/office-spreadsheets/tasks/annotations.md +12 -30
- package/assets/skills/office-spreadsheets/tasks/create-workbook.md +5 -5
- package/assets/skills/office-spreadsheets/tasks/diff-workbooks.md +2 -2
- package/assets/skills/office-spreadsheets/tasks/edit-workbook.md +5 -5
- package/assets/skills/office-spreadsheets/tasks/inspect-workbook.md +9 -9
- package/assets/skills/office-spreadsheets/tasks/recalc-and-check.md +10 -30
- package/assets/skills/shared/annotation-recipes.md +98 -120
- package/assets/skills/shared/common-workflow.md +70 -80
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Task: charts, tables and speaker notes
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
15
|
-
|
|
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
|
|
18
|
-
|
|
19
|
-
`
|
|
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
|
-
-
|
|
25
|
-
|
|
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
|
|
39
|
-
widths, alignment and
|
|
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
|
|
51
|
-
|
|
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`
|
|
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
|
-
|
|
73
|
-
|
|
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
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
9
|
-
[style-guidelines](../references/style-guidelines.md)
|
|
10
|
-
- Evidence: numbers, charts, tables
|
|
11
|
-
|
|
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
|
|
69
|
-
|
|
70
|
-
|
|
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,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
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
|
|
18
|
-
gate gives every shape's rect in inches,
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
60
|
-
`subtitle`, `bullets`, `table`, `chart`, `image`).
|
|
61
|
-
|
|
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 |
|
|
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
|
|
93
|
-
|
|
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.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Task: inspect and verify a deck
|
|
2
2
|
|
|
3
|
-
Verification is reading the
|
|
4
|
-
|
|
3
|
+
Verification is reading the file back and looking at it. Each tool prints one
|
|
4
|
+
JSON object; `passed` is the decision.
|
|
5
5
|
|
|
6
6
|
## 1. What is in the file
|
|
7
7
|
|
|
@@ -10,8 +10,7 @@ print one JSON object each; `passed` is the decision.
|
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
Per slide: title, all text, tables as rows, charts with type/title/categories/
|
|
13
|
-
series, image count.
|
|
14
|
-
meant to write is the content that was written.
|
|
13
|
+
series, image count. Cheapest check that what was written is what was intended.
|
|
15
14
|
|
|
16
15
|
## 2. Is the package coherent
|
|
17
16
|
|
|
@@ -19,10 +18,10 @@ meant to write is the content that was written.
|
|
|
19
18
|
"<python>" "<skill>/container_tools/inspect_presentation_package_integrity.py" --input deck.pptx
|
|
20
19
|
```
|
|
21
20
|
|
|
22
|
-
Checks required parts, slide/master presence, dangling relationships,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
Checks required parts, slide/master presence, dangling relationships, unparseable
|
|
22
|
+
XML, slide-count drift, duplicate parts; reports part counts (`slides`, `layouts`,
|
|
23
|
+
`masters`, `charts`, `notesSlides`, `media`, `embeddings`). Zero `embeddings` on a
|
|
24
|
+
chart means lost data.
|
|
26
25
|
|
|
27
26
|
## 3. Does the layout hold
|
|
28
27
|
|
|
@@ -30,13 +29,12 @@ does not parse, slide count drift and duplicate parts, then reports part counts
|
|
|
30
29
|
"<python>" "<skill>/container_tools/inspect_presentation_layout_geometry.py" --input deck.pptx --json-out geometry.json
|
|
31
30
|
```
|
|
32
31
|
|
|
33
|
-
`fail`
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Add `--strict` to make review findings blocking for a formal deck.
|
|
32
|
+
`fail` blocks delivery: shape outside the slide, degenerate size, text that
|
|
33
|
+
cannot fit its frame, table outside the slide, chart or table covered by another
|
|
34
|
+
shape. `review` needs a decision: text overlap, empty placeholder, title under
|
|
35
|
+
28 pt, body under 14 pt, heading ending in a full stop, connector across text, a
|
|
36
|
+
chart duplicating a table's labels. `--strict` makes review blocking for a formal
|
|
37
|
+
deck.
|
|
40
38
|
|
|
41
39
|
## 4. Are the numbers real
|
|
42
40
|
|
|
@@ -51,11 +49,11 @@ Add `--strict` to make review findings blocking for a formal deck.
|
|
|
51
49
|
- Quantitative charts: every declared chart must be a real chart part with a
|
|
52
50
|
readable series, and in the default `portable` mode must carry its embedded
|
|
53
51
|
workbook.
|
|
54
|
-
- Table arithmetic: only declared totals are enforced,
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
- Table arithmetic: only declared totals are enforced, against displayed
|
|
53
|
+
rounding; non-additive columns (unit price, ratio, percent) are skipped rather
|
|
54
|
+
than summed wrongly.
|
|
57
55
|
|
|
58
|
-
`totals.json` names the contract
|
|
56
|
+
`totals.json` names the contract:
|
|
59
57
|
|
|
60
58
|
```json
|
|
61
59
|
{ "contracts": [{ "slide": 4, "table": 1, "total_row": 6, "columns": [1, 2] }] }
|
|
@@ -67,32 +65,31 @@ Add `--strict` to make review findings blocking for a formal deck.
|
|
|
67
65
|
"<python>" "<skill>/container_tools/render_slides.py" --input deck.pptx --out-dir preview
|
|
68
66
|
```
|
|
69
67
|
|
|
70
|
-
Writes `slide-NN.png` plus `render.json
|
|
71
|
-
|
|
68
|
+
Writes `slide-NN.png` plus `render.json`; `read_image` every PNG — an unlooked-at
|
|
69
|
+
render is not verification.
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
Whole deck at once:
|
|
74
72
|
|
|
75
73
|
```bash
|
|
76
74
|
"<python>" "<skill>/template_following_scripts/make_contact_sheet.py" --dir preview --out sheet.png --columns 3
|
|
77
75
|
```
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
Or `"<skill>/container_tools/create_montage.py` with an explicit file list.
|
|
80
78
|
|
|
81
|
-
Look for: clipped text, overlapping blocks, a title
|
|
82
|
-
|
|
83
|
-
title.
|
|
79
|
+
Look for: clipped text, overlapping blocks, a reflowed title, a chart point
|
|
80
|
+
invisible at thumbnail size, a stretched photograph, a slide with no title.
|
|
84
81
|
|
|
85
82
|
## 6. When nothing can render
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
`
|
|
89
|
-
PyMuPDF geometry preview
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
Without the DSH LibreOffice kit (`office_status` → `renderers.available: false`,
|
|
85
|
+
with a `remedy`), `render_slides.py` falls back to `--engine draft`, a
|
|
86
|
+
PyMuPDF geometry preview: placement, overflow, overlap — not typography or theme
|
|
87
|
+
chrome. Say so: "verified as a geometry preview" is honest; "looks great" from an
|
|
88
|
+
approximate render is not.
|
|
92
89
|
|
|
93
|
-
If even the preview cannot run, the
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
If even the preview cannot run, report the failing command, the slide count from
|
|
91
|
+
`pptx read`, and the gate results; name the renderer to install for a visual
|
|
92
|
+
check.
|
|
96
93
|
|
|
97
94
|
## Gate summary
|
|
98
95
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Task: follow a supplied template
|
|
2
2
|
|
|
3
3
|
Use this when the user hands over a `.pptx` and says "use our template" or "match
|
|
4
|
-
this deck". The design is
|
|
5
|
-
own slides.
|
|
4
|
+
this deck". The design is decided; put content into its own slides.
|
|
6
5
|
|
|
7
6
|
## 1. Inspect
|
|
8
7
|
|
|
@@ -10,16 +9,14 @@ own slides.
|
|
|
10
9
|
"<python>" "<skill>/template_following_scripts/inspect_template_deck.py" --template brand.pptx --out-dir template-inspect
|
|
11
10
|
```
|
|
12
11
|
|
|
13
|
-
Outputs:
|
|
14
|
-
|
|
15
12
|
- `template-inspect.ndjson` — one JSON line per slide: layout name, layout
|
|
16
13
|
placeholders, slide placeholders (index, kind, rect in inches, text), shape
|
|
17
|
-
counts, text excerpt,
|
|
14
|
+
counts, text excerpt, full-bleed background art flag.
|
|
18
15
|
- `template-manifest.json` — slide size, aspect ratio, layout names, theme font
|
|
19
|
-
names,
|
|
16
|
+
names, `backgroundArtSlides`.
|
|
20
17
|
|
|
21
|
-
Read `backgroundArtSlides`
|
|
22
|
-
|
|
18
|
+
Read `backgroundArtSlides` first: those slides already carry artwork, so a new
|
|
19
|
+
opaque panel covers it.
|
|
23
20
|
|
|
24
21
|
## 2. Plan
|
|
25
22
|
|
|
@@ -65,13 +62,13 @@ Write `frame-map.json`:
|
|
|
65
62
|
|
|
66
63
|
Allowed actions: `rewrite`, `rewrite-and-reposition`, `replace`, `delete`,
|
|
67
64
|
`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
|
-
`
|
|
70
|
-
|
|
65
|
+
fractions, used with `rewrite-and-reposition`. Elements whose `role` is `brand`,
|
|
66
|
+
`logo`, `bumper`, `divider`, `section`, `chrome` or `footer` must stay `keep` —
|
|
67
|
+
they are the template.
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
New shapes are opt-in: set `newPrimitives.allowed` and justify it. The validator
|
|
70
|
+
rejects additions without that, because "one extra box" is how a branded deck
|
|
71
|
+
stops matching brand.
|
|
75
72
|
|
|
76
73
|
## 3. Validate
|
|
77
74
|
|
|
@@ -79,10 +76,10 @@ box" is how a branded deck stops matching brand.
|
|
|
79
76
|
"<python>" "<skill>/template_following_scripts/validate_template_plan.py" --plan frame-map.json
|
|
80
77
|
```
|
|
81
78
|
|
|
82
|
-
Rejects
|
|
79
|
+
Rejects unknown action, edited preserved role, zone outside 0–1, non-sequential
|
|
83
80
|
slide numbers, missing justification for new primitives, and duplicate source
|
|
84
|
-
slides (a warning
|
|
85
|
-
|
|
81
|
+
slides (a warning: shared artwork — fine for a repeated divider, usually a
|
|
82
|
+
copy-paste mistake otherwise).
|
|
86
83
|
|
|
87
84
|
## 4. Build
|
|
88
85
|
|
|
@@ -90,12 +87,11 @@ repeated section divider, usually a copy-paste mistake otherwise).
|
|
|
90
87
|
"<python>" "<skill>/template_following_scripts/prepare_template_starter_deck.py" --template brand.pptx --plan frame-map.json --out starter.pptx
|
|
91
88
|
```
|
|
92
89
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
template has no family for a slide you need.
|
|
90
|
+
Keeps only the mapped source slides in plan order and applies the actions. It
|
|
91
|
+
refuses duplicate source slides (reuses slides rather than cloning parts). The
|
|
92
|
+
report lists applied actions and any empty placeholder. Extend with
|
|
93
|
+
`container_tools/add_slides.py` or the recipes when the template has no family
|
|
94
|
+
for a slide you need.
|
|
99
95
|
|
|
100
96
|
## 5. Check fidelity
|
|
101
97
|
|
|
@@ -118,8 +114,8 @@ template has no family for a slide you need.
|
|
|
118
114
|
}
|
|
119
115
|
```
|
|
120
116
|
|
|
121
|
-
Both print `passed`.
|
|
122
|
-
|
|
117
|
+
Both print `passed`. No requirements → deliberate no-op pass: pass a file or you
|
|
118
|
+
have checked nothing.
|
|
123
119
|
|
|
124
120
|
## 6. Look at it
|
|
125
121
|
|
|
@@ -127,6 +123,5 @@ no-op pass — pass a requirements file or you have not checked anything.
|
|
|
127
123
|
"<python>" "<skill>/container_tools/render_slides.py" --input starter.pptx --out-dir starter-preview
|
|
128
124
|
```
|
|
129
125
|
|
|
130
|
-
Compare
|
|
131
|
-
in the wrong family,
|
|
132
|
-
exists to catch.
|
|
126
|
+
Compare with the source slides: this catches an overflowed placeholder, a title
|
|
127
|
+
in the wrong family, a panel over the corner logo.
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Create, inspect, edit, recalculate, and verify Excel
|
|
2
|
+
description: Create, inspect, edit, recalculate, render, and verify Excel spreadsheets (.xlsx/.csv) with openpyxl recipes, formula patterns, and the bundled Office helper CLI.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Spreadsheets (.xlsx)
|
|
6
6
|
|
|
7
|
-
A
|
|
7
|
+
A cell holds a value, a format, and possibly a formula string. openpyxl writes all three and evaluates none: a new formula has no cached result, so `xlsx read` shows `=SUM(B2:B9)` where the user expects `1,950,400`. Only an engine calculates — `xlsx recalc` through the DSH LibreOffice kit (cross-platform), or the app the user opens the file in. Work in that order: write values and formulas, read back for structure, recalculate for numbers, render for appearance.
|
|
8
8
|
|
|
9
|
-
| User job | What is
|
|
9
|
+
| User job | What is happening | Fast path |
|
|
10
10
|
| --- | --- | --- |
|
|
11
|
-
| Build a new workbook | Cells written
|
|
11
|
+
| Build a new workbook | Cells written from A1; `=`-prefixed strings become formulas; styles are per-cell; sheets get names, widths, freeze panes, merges | `xlsx create` spec, `tasks/create-workbook.md` |
|
|
12
12
|
| Change cells in an existing file | Only the cells you name change; a re-save can drop objects openpyxl does not model (pivots, foreign charts) | `container_tools/set_cells.py` and friends, `tasks/edit-workbook.md` |
|
|
13
|
-
|
|
|
14
|
-
| Inventory a file you did not write |
|
|
15
|
-
| Compare two versions | Cell-by-cell walk
|
|
16
|
-
| Prove the numbers are real | Recalculate
|
|
17
|
-
| Format numbers, conditions, names, charts, tables | Number formats, conditional-formatting rules, defined names, native chart objects, Excel Tables | `recipes/*.md` (openpyxl patterns
|
|
13
|
+
| Workbook open in Excel/WPS must change live | The target is the window, not the file: unsaved user edits are in play and a COM write is not transactional. **Windows only** — on macOS/Linux the live tool exits 3 with a remedy; edit the file instead | `../excel-live-control/SKILL.md` |
|
|
14
|
+
| Inventory a file you did not write | Sheets, used range, formulas vs values, merged ranges, conditional formats, defined names, charts | `container_tools/inspect_workbook.py` |
|
|
15
|
+
| Compare two versions | Cell-by-cell walk at formula-, format-, and structure-aware levels | `container_tools/diff_workbooks.py`, `tasks/diff-workbooks.md` |
|
|
16
|
+
| Prove the numbers are real | Recalculate, then check every formula cell has a value, no error, no dangling sheet | `xlsx recalc` + `container_tools/recalc_gate.py`, `tasks/recalc-and-check.md` |
|
|
17
|
+
| Format numbers, conditions, names, charts, tables | Number formats, conditional-formatting rules, defined names, native chart objects, Excel Tables | `recipes/*.md` (runnable openpyxl patterns) |
|
|
18
18
|
| Answer a question about a file | Read values, not formulas; quote the cells you read | `tasks/analyze-workbook.md` |
|
|
19
19
|
| Spreadsheet lives in Google Sheets | Not this runtime — see `routing/google-sheets.md` | — |
|
|
20
20
|
|
|
21
|
-
Sheet and range semantics
|
|
21
|
+
Sheet and range semantics come before any edit: `B4:D9` is a rectangle, `'Build'!E14` is a cross-sheet reference whose sheet name needs quotes when it contains spaces, and a merged range is one value plus a lot of emptiness. Number formats are display only — the stored value keeps full precision, so never round data to make it look right.
|
|
22
22
|
|
|
23
23
|
## Before any file work
|
|
24
24
|
|
|
@@ -29,54 +29,47 @@ Sheet and range semantics matter before any edit: `B4:D9` is a rectangle, `'Buil
|
|
|
29
29
|
|
|
30
30
|
## Delivery
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Hand the finished file to the user with the `present` tool, then summarise in one sentence what changed. A bare path is not delivery: the chat transcript renders `.docx`/`.pptx`/`.xlsx`/`.pdf` links as "二进制文件,无法显示改动" and the user cannot open them.
|
|
33
33
|
|
|
34
34
|
- Creating a file: write it into the user's workspace, verify it, then `present`.
|
|
35
|
-
- Editing an existing file: never overwrite the original. Write `<original>-edited.<ext>` (or
|
|
35
|
+
- Editing an existing file: never overwrite the original. Write `<original>-edited.<ext>` (or the name the user asked for), verify it, `present` it, and state both paths.
|
|
36
36
|
|
|
37
37
|
## Annotations
|
|
38
38
|
|
|
39
|
-
The user may reply with an `office-annotations` block: `[{ page, text, requirement, region: { left, top, width, height } }]`. `region` is normalised 0–1 against the rendered preview page
|
|
39
|
+
The user may reply with an `office-annotations` block: `[{ page, text, requirement, region: { left, top, width, height } }]`. `region` is normalised 0–1 against the rendered preview page; `requirement` is free-form natural language. Treat it as a change request, not editor state.
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
For xlsx the payload is `{ target, fileName, text: "", requirement, region, imageName, unmapped: true }`: no `page`, no `sheet`, no `range`. The preview client cannot resolve a cell from the drag and refuses to fake one. So:
|
|
44
|
-
|
|
45
|
-
1. `read_image` the attachment named `imageName` — it is a screenshot of the area the user marked. Note visible headers, row labels, and values.
|
|
46
|
-
2. Run `"<python>" "<cli>" xlsx read --input "<file>" --json-out "<dump>.json"` and match those values to sheets and A1 addresses; `container_tools/inspect_workbook.py` adds formulas, merged ranges, and names when the match is ambiguous.
|
|
47
|
-
3. State the resolved sheet and range back to the user before editing ("`Pipeline!D2:D13`, the Amount column"), and ask if two sheets or columns match.
|
|
48
|
-
4. Never convert region pixels into a cell address. Full recipe: `tasks/annotations.md` and `"<shared>/annotation-recipes.md"`.
|
|
41
|
+
For xlsx the payload is `{ target, fileName, text: "", requirement, region, imageName, unmapped: true }`: no `page`, no `sheet`, no `range`, because the preview client cannot resolve a cell from the drag and refuses to fake one. So: `read_image` the attachment named `imageName`, match the visible values to sheets and A1 addresses with `"<python>" "<cli>" xlsx read --input "<file>" --json-out "<dump>.json"`, state the resolved sheet and range before editing ("`Pipeline!D2:D13`, the Amount column"), ask when two sheets or columns match, then apply the smallest edit that satisfies `requirement`, re-render, and confirm the region now looks right. Never convert region pixels into a cell address. When the payload cannot be mapped to a concrete object, do not guess silently — say what you could not locate. Full recipe: `tasks/annotations.md` and `"<shared>/annotation-recipes.md"`.
|
|
49
42
|
|
|
50
43
|
## Verify
|
|
51
44
|
|
|
52
45
|
Three checks, in this order, after every mutation:
|
|
53
46
|
|
|
54
|
-
1. **Structure and values.** `"<python>" "<cli>" xlsx read --input "<file>"` proves the cells you wrote are where you wrote them
|
|
55
|
-
2. **Numbers.** If
|
|
56
|
-
3. **Appearance.** `"<python>" "<cli>" xlsx render --input "<file>" --out-dir "<render-dir>"`, then `read_image` each PNG. Check titles and labels, `###` columns, clipped numbers, charts cut off by the print area, plots with no categories, legends naming `Series 1`, conditional formatting that never fired, and blank pages.
|
|
47
|
+
1. **Structure and values.** `"<python>" "<cli>" xlsx read --input "<file>"` proves the cells you wrote are where you wrote them. `container_tools/inspect_workbook.py` proves charts, tables, conditional formats, names, and merges survived.
|
|
48
|
+
2. **Numbers.** If a formula changed or was added, run `"<python>" "<cli>" xlsx recalc --input "<file>" --out "<file>"`, then `container_tools/recalc_gate.py --input "<file>"`. Recalc fails only when the kit is missing, and `recalc_gate.py` then reports `unverified` — say that plainly instead of presenting an empty cache as a result. Flags, exit codes, and what the gate reports: `tasks/recalc-and-check.md`.
|
|
49
|
+
3. **Appearance.** `"<python>" "<cli>" xlsx render --input "<file>" --out-dir "<render-dir>"`, then `read_image` each PNG. Check titles and labels, `###` columns, clipped numbers, charts cut off by the print area, plots with no categories, legends naming `Series 1`, conditional formatting that never fired, and blank pages. When the LibreOffice kit is missing the command fails explicitly: report the file as structurally verified but visually unchecked, and offer to rebuild from a spec.
|
|
57
50
|
|
|
58
51
|
Two or three render/fix passes are normal. If a defect survives three, say what still looks wrong.
|
|
59
52
|
|
|
60
53
|
## Mutation tools
|
|
61
54
|
|
|
62
|
-
The CLI is read-only for `.xlsx`: `create`, `read`, `render`, `status`, `recalc
|
|
55
|
+
The CLI is read-only for `.xlsx`: `create`, `read`, `render`, `status`, `recalc`, and nothing else. Every change to an existing workbook goes through these openpyxl tools. Each reads `--input`, writes `<input>-edited.xlsx` unless you pass `--out`, prints one JSON object on stdout, and exits non-zero with a JSON `error` on stderr when it refuses.
|
|
63
56
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
57
|
+
- `sheet_ops.py` — `--add NAME`, `--rename OLD=NEW`, `--delete NAME`, `--order "A,B,C"`. Renaming a sheet does not update the formulas that point at it; deleting the last sheet is refused.
|
|
58
|
+
- `set_cells.py` — `--sheet S --set B2=42 --set C3="=SUM(C2:C9)"`, or `--spec cells.json`. It does not parse dates for you: write `2026-01-31` and format the cell, or pass a serial.
|
|
59
|
+
- `append_rows.py` — `--sheet S --rows '[[...],[...]]'`, or `--rows-file rows.json`. It does not extend an Excel Table, copy the row above's formula, or grow charts and conditional formats.
|
|
60
|
+
- `style_cells.py` — `--sheet S --range A1:D1 --style '{"bold":true}'`, or `--spec styles.json`. No autofit, and it will not restyle cells outside the range.
|
|
61
|
+
- `add_chart.py` — `--sheet S --type line --data-min-col ... --cat-min-row ...`, or `--spec chart.json`. It cannot set axis number formats, series colours, or a legend position, and a one-row data range is treated as one series of many points.
|
|
62
|
+
- `add_image.py` — `--sheet S --path logo.png --anchor B2 [--width 480]`. It cannot update an embedded image when the file on disk changes.
|
|
63
|
+
|
|
64
|
+
Chain by naming outputs: `set_cells.py --input book.xlsx --out step1.xlsx`, then `style_cells.py --input step1.xlsx --out step2.xlsx`; without `--out` each tool writes `book-edited.xlsx` next to the input and the next step would read the unedited original.
|
|
72
65
|
|
|
73
|
-
|
|
66
|
+
Values: numbers, booleans, `null`, and JSON arrays parse; anything else is text, and a leading `=` is stored as a formula. `--set B3=` stores an empty string, which is not a blank cell — leave a cell out of the assignment to keep it blank.
|
|
74
67
|
|
|
75
|
-
|
|
68
|
+
Runnable invocations with real paths: `tasks/edit-workbook.md` `## Mutation tools`.
|
|
76
69
|
|
|
77
70
|
## Formulas you will write
|
|
78
71
|
|
|
79
|
-
Write the formula text a person would type
|
|
72
|
+
Write the formula text a person would type. openpyxl stores it verbatim and never evaluates it.
|
|
80
73
|
|
|
81
74
|
- Anchoring: `C8` moves when filled, `C$4` pins the row (a period header), `$A8` pins the column (an item label), `$B$3` pins one cell (a rate or case selector). `=SUMIFS(Amount,Month,C$4,Item,$A8)` is the shape a grid needs.
|
|
82
75
|
- Aggregation: `SUM`, `SUMIFS`, `COUNTIFS`, `AVERAGEIFS`, `SUMPRODUCT` for quantity × rate pairs, `PRODUCT` for chained factors (it silently skips blanks, so a missing input looks valid).
|
|
@@ -85,7 +78,7 @@ Write the formula text a person would type; openpyxl stores it verbatim and neve
|
|
|
85
78
|
- No `LET`, no dynamic arrays, no `LAMBDA`: the engines that read these files disagree on them.
|
|
86
79
|
- Cross-sheet references quote the name: `='Build'!E14`, `='Case A'!$B$4`.
|
|
87
80
|
|
|
88
|
-
|
|
81
|
+
Recalculate before anyone reads a number — see `## Verify`. Patterns and dates: `references/formula-patterns.md`.
|
|
89
82
|
|
|
90
83
|
## Tasks
|
|
91
84
|
|
|
@@ -107,8 +100,8 @@ Background: `references/workbook-structure.md` (tab roles and layout), `referenc
|
|
|
107
100
|
|
|
108
101
|
## Edit discipline
|
|
109
102
|
|
|
110
|
-
An existing workbook is the reference: its structure, formula style, formats, and terminology are what the user expects to keep seeing. Change the cells the request names and the formulas those cells feed. Everything else — other sheets, pivot sources, shared formulas, named ranges, conditional formats, data validation, protection, hidden rows, freeze panes, chart contents — stays untouched unless the request or a real dependency forces it. Never flatten formulas to values because it is easier, never autofit whole sheets for a visual tweak, and never quietly repair errors the user did not ask about: list them and ask.
|
|
103
|
+
An existing workbook is the reference: its structure, formula style, formats, and terminology are what the user expects to keep seeing. Change the cells the request names and the formulas those cells feed. Everything else — other sheets, pivot sources, shared formulas, named ranges, conditional formats, data validation, protection, hidden rows, freeze panes, chart contents — stays untouched unless the request or a real dependency forces it. Never flatten formulas to values because it is easier, never autofit whole sheets for a visual tweak, and never quietly repair errors the user did not ask about: list them and ask. Failure modes: `tasks/edit-workbook.md`.
|
|
111
104
|
|
|
112
105
|
## Shared workflow
|
|
113
106
|
|
|
114
|
-
|
|
107
|
+
`"<shared>/common-workflow.md"` owns the create-or-edit decision, the failure ladder, and the edit naming rule. `"<shared>/annotation-recipes.md"` owns the payload shapes the client sends.
|