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.
Files changed (113) 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/tasks/accessibility_a11y.md +16 -22
  21. package/assets/skills/office-documents/tasks/captions_crossrefs.md +23 -26
  22. package/assets/skills/office-documents/tasks/clean_tracked_changes.md +17 -22
  23. package/assets/skills/office-documents/tasks/comments_manage.md +9 -11
  24. package/assets/skills/office-documents/tasks/compare_diff.md +10 -16
  25. package/assets/skills/office-documents/tasks/create_edit.md +14 -16
  26. package/assets/skills/office-documents/tasks/equations.md +17 -28
  27. package/assets/skills/office-documents/tasks/fields_update.md +14 -16
  28. package/assets/skills/office-documents/tasks/fixtures_edge_cases.md +19 -33
  29. package/assets/skills/office-documents/tasks/footnotes_endnotes.md +12 -14
  30. package/assets/skills/office-documents/tasks/forms_content_controls.md +16 -20
  31. package/assets/skills/office-documents/tasks/headings_numbering.md +17 -22
  32. package/assets/skills/office-documents/tasks/images_figures.md +15 -25
  33. package/assets/skills/office-documents/tasks/multi_doc_merge.md +13 -23
  34. package/assets/skills/office-documents/tasks/navigation_internal_links.md +18 -21
  35. package/assets/skills/office-documents/tasks/privacy_scrub_metadata.md +16 -22
  36. package/assets/skills/office-documents/tasks/protection_restrict_editing.md +19 -21
  37. package/assets/skills/office-documents/tasks/read_review.md +9 -20
  38. package/assets/skills/office-documents/tasks/redaction_anonymization.md +17 -18
  39. package/assets/skills/office-documents/tasks/sections_layout.md +16 -23
  40. package/assets/skills/office-documents/tasks/style_lint_normalize.md +18 -22
  41. package/assets/skills/office-documents/tasks/tables_spreadsheets.md +21 -31
  42. package/assets/skills/office-documents/tasks/templates_style_packs.md +17 -21
  43. package/assets/skills/office-documents/tasks/toc_workflow.md +10 -14
  44. package/assets/skills/office-documents/tasks/verify_render.md +11 -23
  45. package/assets/skills/office-documents/tasks/watermarks_background.md +11 -15
  46. package/assets/skills/office-documents/troubleshooting/libreoffice_headless.md +6 -6
  47. package/assets/skills/office-documents/troubleshooting/run_splitting.md +12 -12
  48. package/assets/skills/office-pdf/SKILL.md +36 -51
  49. package/assets/skills/office-pdf/references/form-fields.md +20 -20
  50. package/assets/skills/office-pdf/references/geometry.md +10 -10
  51. package/assets/skills/office-pdf/references/layout-quality.md +13 -13
  52. package/assets/skills/office-pdf/references/limits.md +12 -56
  53. package/assets/skills/office-pdf/tasks/annotations.md +5 -5
  54. package/assets/skills/office-pdf/tasks/create.md +6 -9
  55. package/assets/skills/office-pdf/tasks/edit-pages.md +14 -14
  56. package/assets/skills/office-pdf/tasks/forms.md +15 -15
  57. package/assets/skills/office-pdf/tasks/read.md +9 -9
  58. package/assets/skills/office-pdf/tasks/redact.md +18 -18
  59. package/assets/skills/office-pdf/tasks/stamp.md +10 -10
  60. package/assets/skills/office-presentations/SKILL.md +71 -91
  61. package/assets/skills/office-presentations/container_tools/render_slides.py +1 -1
  62. package/assets/skills/office-presentations/domain_guidance/finance.md +16 -16
  63. package/assets/skills/office-presentations/recipes/README.md +24 -35
  64. package/assets/skills/office-presentations/recipes/autolayout.md +12 -13
  65. package/assets/skills/office-presentations/recipes/connectors.md +11 -12
  66. package/assets/skills/office-presentations/recipes/images.md +11 -12
  67. package/assets/skills/office-presentations/recipes/master-and-layouts.md +18 -18
  68. package/assets/skills/office-presentations/recipes/native-charts.md +8 -8
  69. package/assets/skills/office-presentations/recipes/rich-text-runs.md +13 -13
  70. package/assets/skills/office-presentations/recipes/speaker-notes.md +7 -7
  71. package/assets/skills/office-presentations/recipes/tables.md +14 -14
  72. package/assets/skills/office-presentations/recipes/textbox-at-coordinate.md +9 -9
  73. package/assets/skills/office-presentations/recipes/theme-tokens.md +7 -8
  74. package/assets/skills/office-presentations/references/authoring-workflow.md +38 -43
  75. package/assets/skills/office-presentations/references/finalization.md +10 -12
  76. package/assets/skills/office-presentations/references/native-bullets.md +14 -18
  77. package/assets/skills/office-presentations/references/native-evidence.md +18 -32
  78. package/assets/skills/office-presentations/references/style-guidelines.md +27 -32
  79. package/assets/skills/office-presentations/references/templates.md +31 -60
  80. package/assets/skills/office-presentations/routing/google_slides.md +4 -4
  81. package/assets/skills/office-presentations/tasks/apply-annotations.md +17 -17
  82. package/assets/skills/office-presentations/tasks/charts-tables-notes.md +20 -23
  83. package/assets/skills/office-presentations/tasks/create-deck.md +19 -19
  84. package/assets/skills/office-presentations/tasks/edit-deck.md +14 -16
  85. package/assets/skills/office-presentations/tasks/inspect-and-verify.md +31 -34
  86. package/assets/skills/office-presentations/tasks/template-following.md +23 -28
  87. package/assets/skills/office-spreadsheets/SKILL.md +32 -39
  88. package/assets/skills/office-spreadsheets/recipes/charts.md +8 -26
  89. package/assets/skills/office-spreadsheets/recipes/conditional-formats.md +9 -26
  90. package/assets/skills/office-spreadsheets/recipes/data-tables.md +7 -23
  91. package/assets/skills/office-spreadsheets/recipes/named-ranges.md +8 -21
  92. package/assets/skills/office-spreadsheets/recipes/number-formats.md +7 -23
  93. package/assets/skills/office-spreadsheets/recipes/sparklines.md +7 -20
  94. package/assets/skills/office-spreadsheets/references/charts.md +15 -34
  95. package/assets/skills/office-spreadsheets/references/domain/financial-models.md +10 -25
  96. package/assets/skills/office-spreadsheets/references/domain/healthcare.md +8 -19
  97. package/assets/skills/office-spreadsheets/references/domain/marketing.md +8 -22
  98. package/assets/skills/office-spreadsheets/references/domain/research.md +8 -19
  99. package/assets/skills/office-spreadsheets/references/formula-patterns.md +20 -50
  100. package/assets/skills/office-spreadsheets/references/style-guidelines.md +19 -44
  101. package/assets/skills/office-spreadsheets/references/workbook-structure.md +12 -35
  102. package/assets/skills/office-spreadsheets/routing/google-sheets.md +11 -26
  103. package/assets/skills/office-spreadsheets/tasks/analyze-workbook.md +10 -25
  104. package/assets/skills/office-spreadsheets/tasks/annotations.md +12 -30
  105. package/assets/skills/office-spreadsheets/tasks/create-workbook.md +5 -5
  106. package/assets/skills/office-spreadsheets/tasks/diff-workbooks.md +2 -2
  107. package/assets/skills/office-spreadsheets/tasks/edit-workbook.md +5 -5
  108. package/assets/skills/office-spreadsheets/tasks/inspect-workbook.md +9 -9
  109. package/assets/skills/office-spreadsheets/tasks/recalc-and-check.md +10 -30
  110. package/assets/skills/shared/annotation-recipes.md +98 -120
  111. package/assets/skills/shared/common-workflow.md +70 -80
  112. package/dist/index.js +1 -1
  113. package/package.json +1 -1
@@ -1,51 +1,42 @@
1
1
  ---
2
- description: Drive a workbook that is already open in Excel or WPS Spreadsheets over COM — read cells, write values and formulas, style ranges, add charts and tables, recalculate, save, and report the exact ranges touched.
2
+ description: Drive a workbook that is already open in Excel or WPS Spreadsheets on Windows over COM: read cells, write values and formulas, style ranges, add charts and tables, recalculate, save, and report the exact ranges touched.
3
3
  ---
4
4
 
5
5
  # Live spreadsheets (Excel / WPS)
6
6
 
7
- > Windows only. This skill drives an already-open Excel or WPS Spreadsheets window
8
- > through COM using Windows PowerShell 5.1 (`Marshal.GetActiveObject`, which
9
- > PowerShell 7 dropped). On macOS and Linux every command exits `3` with
10
- > `stage: "powershell"` and a remedy; use the file-based `xlsx` verbs there instead.
7
+ Windows only. Drives an open Excel or WPS Spreadsheets window through COM with Windows
8
+ PowerShell 5.1 (`Marshal.GetActiveObject`; PowerShell 7 dropped it). On macOS and Linux
9
+ every command exits `3` with `stage: "powershell"` and a remedy; use the file-based `xlsx`
10
+ verbs there.
11
11
 
12
12
  ## What "live" means here
13
13
 
14
- The workbook is open in a running Excel or WPS Spreadsheets window, and the user is
15
- looking at it. The file on disk may be behind the window, may not exist yet, and may
16
- carry edits the user has not saved. A live call changes the *open document*: the cells
17
- the user is staring at update while they watch, and saving is a separate decision.
14
+ The workbook is open and the user is watching. The disk file may lag the window, not exist
15
+ yet, or hold unsaved edits. A live call changes the open document; saving is a separate
16
+ decision.
18
17
 
19
- That one sentence drives everything below:
20
-
21
- - The target is `Application.ActiveWorkbook`-shaped state, not a path. Address it by
22
- workbook name, sheet name and A1 range, never by "the active sheet" or "the selection".
23
- - Nothing is transactional. A failed call leaves whatever already landed exactly where
24
- it landed. Read before retrying; never replay a half-applied batch.
25
- - The disk file is not the deliverable. What the user sees in the window is. Saving is
26
- an explicit act you announce.
18
+ - Address the open state, not a path: workbook name, sheet name, A1 range. Never "the
19
+ active sheet" or "the selection".
20
+ - Nothing is transactional. A failed call leaves what landed. Read before retrying; never
21
+ replay a half-applied batch.
22
+ - What the user sees matters, not the file on disk.
27
23
 
28
24
  ## Live or file editing?
29
25
 
30
26
  | Situation | Route |
31
27
  | --- | --- |
32
28
  | The user says the file is open, or asks for "the sheet I'm looking at" | this skill |
33
- | They want to watch cells change, iterate on a model with them, or add a chart to the visible sheet | this skill |
34
- | No spreadsheet application is running | `../office-spreadsheets/SKILL.md` — edit the file, then tell them to reopen it |
35
- | Bulk generation, batch jobs, CI, or work that outlives the session | `../office-spreadsheets/SKILL.md` |
36
- | Reading a file to answer a question, with no app open | `../office-spreadsheets/SKILL.md` |
29
+ | They want to watch cells change, iterate on a model, or add a chart to the visible sheet | this skill |
30
+ | Nothing is running, or the job is bulk/CI work, outlives the session, or is a question about a file | `../office-spreadsheets/SKILL.md` — edit the file, then tell them to reopen it |
37
31
 
38
- Never force the live path. If nothing is running, do not launch an application to avoid
39
- talking to the user: say plainly that the workbook must be open, or switch to the file
40
- route and say so.
32
+ Never force the live path. If nothing is running, say the workbook must be open, or switch
33
+ to the file route and say so. Do not launch an application.
41
34
 
42
35
  ## Before you touch anything
43
36
 
44
- 1. Call the `office_status` tool, then take the `## Office runtime` JSON block that the
45
- host appends to `../office-spreadsheets/SKILL.md` (this sub-skill is routed from
46
- there, so that block is where the paths live). Use its `python` value verbatim and
47
- quote every path; this pack's directory is `<skill>/../excel-live-control`, which is
48
- what `<skill>` below means.
37
+ 1. Call `office_status`. The runtime block in `../office-spreadsheets/SKILL.md` holds the
38
+ verified paths: `python` runs these scripts, and its `skill` value is the
39
+ office-spreadsheets directory, so this pack is `<skill>/../excel-live-control`. Quote every path.
49
40
  2. Run `"<python>" "<skill>/container_tools/live_excel.py" --help` once per session.
50
41
  3. Attach and look before writing:
51
42
 
@@ -53,76 +44,64 @@ route and say so.
53
44
  "<python>" "<skill>/container_tools/live_excel.py" info
54
45
  ```
55
46
 
56
- `info` lists every open workbook, the target workbook, its sheets, and per sheet the
57
- used range, charts, tables, pivot tables and protection state.
58
-
59
- 4. If attach fails, the JSON carries a `remediation` string. Relay it as written: open
60
- the workbook in Excel or WPS and keep it open, then ask for the change again. Do not
61
- start an application on the user's behalf.
62
- 5. If more than one workbook is open, the tool refuses to guess. Pass `--workbook` with
63
- the file name (`Budget FY26.xlsx`) or enough of the path to be unambiguous.
64
- 6. Something looks wrong with the environment — attach works but calls fail, or the
65
- application name and vendor disagree — run `--diagnose`. It reports the attach
66
- mechanism, the running application, every workbook and every sheet without mutating
67
- anything.
68
-
69
- Attachment uses `[Runtime.InteropServices.Marshal]::GetActiveObject` from Windows
70
- PowerShell 5.1, trying `Excel.Application` then `Ket.Application` (WPS Spreadsheets).
71
- WPS registers `Excel.Application` as an alias, so the reported application name is not
72
- proof of which product is running; the JSON's `engine.vendor` is derived from
73
- `Application.Path`. Mechanics and the COM object model: `references/office-automation.md`.
47
+ `info` lists open workbooks, the target workbook, its sheets, and per sheet the used
48
+ range, charts, tables, pivots and protection.
49
+ 4. Attach failure returns a `remediation` string. Relay it as written: open the workbook in
50
+ Excel or WPS and keep it open, then retry. Never start an application for the user.
51
+ 5. Several workbooks open: the tool refuses to guess. Pass `--workbook` with a file name
52
+ (`Budget FY26.xlsx`) or an unambiguous path fragment.
53
+ 6. Attach works but calls fail, or name and vendor disagree: run `--diagnose` for the
54
+ attach mechanism, application, workbooks and sheets, with no mutation.
55
+
56
+ Attachment tries `Excel.Application` then `Ket.Application` (WPS). WPS registers
57
+ `Excel.Application` as an alias, so the app name proves nothing; `engine.vendor` comes from
58
+ `Application.Path`. COM object model: `references/office-automation.md`.
74
59
 
75
60
  ## The edit contract
76
61
 
77
- These are not preferences. Every mutating call has to satisfy them.
78
-
79
- - **Touch only what was asked for.** The named sheet and the named ranges. Not the
80
- neighbouring column, not the whole sheet, not "while I'm here".
81
- - **Read before you write.** Call `read_range` on the target first. You need to know
82
- whether a cell holds a value, a formula, or a merged-region fragment, and whether the
83
- user's edits are unsaved before you replace them.
84
- - **Never destroy structure you did not create**: formulas (never flatten to values),
85
- named ranges, conditional formats, shared formulas, data validation, pivots and their
86
- sources, chart series definitions, filters, hidden rows, freeze panes, protection.
87
- - **Never clear more than you can name.** `write_range --clear` clears contents of an
88
- explicit range; it does not remove charts, tables or formats. Clearing a used range to
89
- "start clean" is off-limits.
90
- - **Small writes, batched.** One call per logical block (a column of assumptions, a
91
- sheet of outputs). Rectangular data only: if the range is 6 rows × 2 columns, the JSON
92
- array must be 6 rows of 2 values.
93
- - **Report exactly what you touched.** Every mutating op answers with workbook name and
94
- path, sheet, exact address, row/column/cell counts, and a `warnings` list. Quote that
95
- in your reply — "wrote `Assumptions!C4:D8` (10 cells)" — not "updated the assumptions".
96
- - **Saving is a separate, announced act.** See Delivery.
97
- - **No decorative edits without a request.** Do not restyle a sheet to your taste, do not
98
- autofit whole columns, do not add a header row the user did not ask for.
99
-
100
- If a call fails partway, `read_range` the block you were writing and continue from what
101
- actually landed. Retrying the identical call is how duplicate rows and reversed edits
102
- happen.
62
+ Every mutating call must satisfy these.
63
+
64
+ - **Touch only what was asked for** — the named sheet and ranges.
65
+ - **Read before you write.** `read_range` the target: value, formula or merged fragment,
66
+ and whether user edits are unsaved.
67
+ - **Never destroy structure you did not create**: formulas (never flatten to values), named
68
+ ranges, conditional formats, shared formulas, data validation, pivots and sources, chart
69
+ series, filters, hidden rows, freeze panes, protection.
70
+ - **Never clear more than you can name.** `write_range --clear` clears an explicit range's
71
+ contents; charts, tables and formats survive. Never clear a used range to "start clean".
72
+ - **Batch small writes.** One call per logical block; rectangular only. A 6 × 2 range takes
73
+ 6 rows of 2 values.
74
+ - **Report exactly what you touched.** Every mutating op returns workbook name and path,
75
+ sheet, address, row/column/cell counts and `warnings`. Quote it — "wrote
76
+ `Assumptions!C4:D8` (10 cells)" — not "updated the assumptions".
77
+ - **Saving is separate and announced.** See Delivery.
78
+ - **No decorative edits without a request.** No restyling, whole-column autofit, or
79
+ unrequested header row.
80
+
81
+ If a call fails partway, `read_range` the block and continue from what landed; retrying
82
+ the identical call duplicates rows and reverses edits.
103
83
 
104
84
  ## The tool
105
85
 
106
- `"<skill>/container_tools/live_excel.py"` — one command per operation, one JSON object on
107
- stdout, non-zero exit on failure. It shells out to `powershell.exe`; pywin32, comtypes and
108
- Excel interop assemblies are neither used nor needed.
86
+ `"<skill>/container_tools/live_excel.py"` runs one command per operation, prints one JSON
87
+ object, and exits non-zero on failure. It shells out to `powershell.exe`; pywin32, comtypes
88
+ and Excel interop assemblies are neither used nor needed.
109
89
 
110
90
  | Op | Does | Key options |
111
91
  | --- | --- | --- |
112
- | `info` | workbooks, target workbook, sheet inventory | `--workbook` |
113
- | `read_range` | typed values, optionally formulas and displayed text | `--sheet --range`, `--formulas`, `--display`, `--max-cells` |
114
- | `write_range` | one rectangular block of values | `--sheet --range --data`/`--data-file`, `--clear` |
115
- | `set_formula` | a formula filled across a range, or a cell→formula map | `--range --formula`, or `--cells '{"C1":"=A1+B1"}'`/`--cells-file`, `--r1c1` |
92
+ | `info` | workbooks, target, sheet inventory | `--workbook` |
93
+ | `read_range` | typed values; optional formulas, display text | `--sheet --range`, `--formulas`, `--display`, `--max-cells` |
94
+ | `write_range` | a rectangular block of values | `--sheet --range --data`/`--data-file`, `--clear` |
95
+ | `set_formula` | one formula filled across a range, or a cell→formula map | `--range --formula`, or `--cells '{"C1":"=A1+B1"}'`/`--cells-file`, `--r1c1` |
116
96
  | `style_range` | font, fill, number format, alignment, borders, width, merge | `--style` JSON or `--style-file`, `--merge` |
117
97
  | `add_table` | native table (ListObject) over a range | `--name`, `--style TableStyleMedium2`, `--no-headers` |
118
- | `add_chart` | embedded chart pointed at a range | `--type`, `--data`, `--anchor`, `--title`, `--width`, `--height` |
98
+ | `add_chart` | embedded chart at an anchor, over a source range | `--type`, `--data`, `--anchor`, `--title`, `--width`, `--height` |
119
99
  | `recalc` | `CalculateFull` on every open workbook | — |
120
- | `save` | save in place, or `SaveAs` a copy | `--path` |
121
- | `close` | close the workbook, optionally quit the application | `--save`, `--discard`, `--quit-app` |
100
+ | `save` | in place, or `SaveAs` a copy | `--path` |
101
+ | `close` | close the workbook, optionally quit the app | `--save`, `--discard`, `--quit-app` |
122
102
 
123
- Global options on every op: `--workbook NAME|PATH`, `--timeout SECONDS` (default 180;
124
- a live call is allowed to take seconds), and `--launch-hidden` (**self-tests only** — it
125
- starts a hidden application, which is wrong for any user-facing edit).
103
+ Global options on every op: `--workbook NAME|PATH`, `--timeout SECONDS` (default 180) and
104
+ `--launch-hidden` (**self-tests only** — a hidden app is wrong for user edits).
126
105
 
127
106
  Style keys: `font_name`, `font_size`, `bold`, `italic`, `color`, `fill` (hex RGB, e.g.
128
107
  `#FFF2CC`), `number_format`, `h_align` (`left|center|right|general|justify`), `v_align`
@@ -143,96 +122,84 @@ Typical first calls:
143
122
  ```
144
123
 
145
124
  Failures print `{"ok": false, "stage": "...", "error": "...", "remediation": "..."}` and
146
- exit 1 (2 for usage errors, 3 when PowerShell itself is unavailable). `stage: "attach"`
147
- means nothing was running; `stage: "com"` means the application refused or failed the
148
- call; read the message before changing the approach.
125
+ exit `1` (operation failure), `2` (usage) or `3` (PowerShell unavailable, timed out, or
126
+ non-Windows). Stages: `attach` (nothing running), `com` (application refused the call),
127
+ `timeout` (dialog or oversized batch), `powershell` (no usable PowerShell), `usage` (bad
128
+ arguments). Read the message before changing approach.
149
129
 
150
- The CLI is the fast path, not the ceiling. When a job needs a COM call it does not wrap —
151
- a sheet tab, freeze panes, a pivot, data validation, shape geometry — extend the script or
152
- drive the application from a short PowerShell snippet, and keep the same reporting and
153
- verification rules. The object model is in `references/office-automation.md`.
130
+ The CLI is the fast path, not the ceiling. For a COM call it does not wrap (a sheet tab,
131
+ freeze panes, a pivot, data validation, shape geometry), extend the script or drive the app
132
+ from a short PowerShell snippet, keeping the reporting and verification rules. Object
133
+ model: `references/office-automation.md`.
154
134
 
155
- What this tool deliberately does not do: create, rename, delete or reorder sheets; delete
156
- ranges or objects; run macros; open a file from disk. A job that needs one of those asks
157
- the user for it, or belongs to the file route in `../office-spreadsheets/SKILL.md`.
135
+ The tool does not create, rename, delete or reorder sheets; delete ranges or objects; run
136
+ macros; or open a file. Such a job asks the user for it, or uses the file route in
137
+ `../office-spreadsheets/SKILL.md`.
158
138
 
159
139
  ## Verification
160
140
 
161
- Do these in order after every batch of edits, before you report anything as done.
162
-
163
- 1. **Read it back.** `read_range` the exact ranges you wrote, with `--formulas` when you
164
- wrote formulas. Compare against what you intended cell by cell.
165
- 2. **No error cells.** The `errors` array in `read_range` lists every cell whose *live*
166
- value is an error (`#DIV/0!`, `#VALUE!`, `#REF!`, `#NAME?`, `#N/A`, …) with its
167
- formula and address. An edit that leaves an error is not finished. A pre-existing
168
- error you did not cause is reported to the user, not silently fixed.
169
- 3. **Numbers.** Run `recalc` after adding or changing formulas, then read the cells
170
- again. A formula that has not been calculated tells you nothing.
171
- 4. **Objects.** If you added a table or chart, run `info` and confirm it in the sheet's
172
- inventory, and read the chart's `source` from `add_chart`'s reply to confirm it points
173
- at the range you meant.
174
- 5. **Appearance.** You cannot screenshot the user's window from here. `--display` on
175
- `read_range` shows the rendered text of each cell (up to 500), which catches `###`
176
- widths, applied number formats and stray `#` — use it when formatting is part of the
177
- request. Otherwise say the visual check is the user's, and ask them to confirm if it
178
- matters.
179
- 6. **Structure.** If the sheet had tables, pivots or charts before you started, `info`
180
- after the edit proves they are still there.
181
- 7. **Report.** Name the workbook, the sheet, every range, and the cell counts.
141
+ After every batch, in order, before reporting done:
142
+
143
+ 1. **Read it back.** `read_range` every range you wrote, `--formulas` when you wrote
144
+ formulas; compare cell by cell.
145
+ 2. **No error cells.** `errors` lists every live error cell (`#DIV/0!`, `#VALUE!`, `#REF!`,
146
+ `#NAME?`, `#N/A`, …) with formula and address. An edit that leaves an error is
147
+ unfinished. Report a pre-existing error; do not silently fix it.
148
+ 3. **Numbers.** `recalc` after formula changes, then re-read. An uncalculated formula tells
149
+ you nothing.
150
+ 4. **Objects.** After adding a table or chart, `info` confirms it in the sheet inventory;
151
+ `add_chart`'s `source` confirms the source range.
152
+ 5. **Appearance.** You cannot screenshot the user's window. `--display` shows up to 500
153
+ cells of rendered text and catches `###`, applied number formats and stray `#`; use it
154
+ when formatting matters. Otherwise the visual check is the user's — ask them to confirm.
155
+ 6. **Structure.** `info` after the edit proves pre-existing tables, pivots and charts
156
+ survive.
157
+ 7. **Report.** Workbook, sheet, every range, cell counts.
182
158
 
183
159
  ## Delivery
184
160
 
185
- The workbook is the user's open document, not an artifact you produced. Say what you did
186
- and what state the document is in; do not save quietly.
187
-
188
- - **Default: leave the document modified and unsaved.** The change is visible in their
189
- window. Tell them so, and tell them Ctrl+S keeps it. This is what keeps you from
190
- overwriting a file they were editing by hand.
191
- - **They asked you to save**: `save` with no `--path` writes the workbook over its own
192
- file. Say "saved `Budget FY26.xlsx`" and give the full path from the reply.
193
- - **Unsaved workbook, or they want an artifact to keep**: `save --path <copy>.xlsx`
194
- writes a copy and leaves the original window dirty. Then `present` that copy — it is a
195
- real file they can open, send, or archive.
196
- - **`.xlsx` in chat**: a path on its own is not delivery. Use the `present` tool on a
197
- saved file, and state both paths when the original and the copy differ.
198
- - **Never** save over the user's file to "make sure it's persisted" without telling them,
199
- and never close their workbook. `close --quit-app` is for cleaning up a self-test
200
- instance, not for tidying the user's desktop.
201
- - If the edit failed partway and the document is dirty with a half-finished change, say
202
- exactly which ranges landed, and offer either to finish them or to close without saving.
161
+ The workbook is the user's document; state what you did and its state. Never save quietly.
162
+
163
+ - **Default: modified and unsaved.** Say so, and that Ctrl+S keeps it. Never overwrite a
164
+ file they were editing by hand.
165
+ - **They asked to save**: `save` with no `--path` overwrites the workbook's file. Say
166
+ "saved `Budget FY26.xlsx`" with the full path from the reply.
167
+ - **Unsaved workbook, or an artifact is wanted**: `save --path <copy>.xlsx` writes a copy
168
+ and leaves the original dirty. `present` that copy.
169
+ - **`.xlsx` in chat**: a path alone is not delivery. `present` a saved file; state both
170
+ paths when original and copy differ.
171
+ - **Never** save over the user's file "to make sure" without telling them, and never close
172
+ their workbook. `close --quit-app` is for self-test cleanup, not the user's desktop.
173
+ - If the edit failed partway, say exactly which ranges landed and offer to finish them or
174
+ close without saving.
203
175
 
204
176
  ## What good content looks like
205
177
 
206
- The mechanics above keep the document intact; these rules keep it useful. The same rules
207
- as the file-editing skill, because a careless live edit damages a document the user is
208
- looking at.
209
-
210
- - **Structure by role, not by tab count.** Inputs, assumptions, calculations, outputs.
211
- Outputs on the left of the tab strip, builds in the middle, inputs on the right; a
212
- terminal check/audit tab for models that need one. Do not restructure a workbook the
213
- user already organised — `workflows/edit_workflows.md`.
214
- - **Formulas that a reviewer can audit.** Anchored references (`$B$3`, `C$4`, `$A8`),
178
+ - **Structure by role, not tab count.** Inputs, assumptions, calculations, outputs. Outputs
179
+ at the left of the tab strip, builds in the middle, inputs on the right; a terminal
180
+ check/audit tab if the model needs one. Do not restructure a workbook the user already
181
+ organised — `workflows/edit_workflows.md`.
182
+ - **Formulas a reviewer can audit.** Anchored references (`$B$3`, `C$4`, `$A8`),
215
183
  `SUMIFS`/`COUNTIFS`/`AVERAGEIFS` over hand-rolled sums, short `IF`, no blanket
216
184
  `IFERROR(...,0)` (`#VALUE!` is information), no `LET`/`LAMBDA`/spill arrays.
217
- `workflows/create_workflows.md` and `references/office-automation.md` for what COM
185
+ `workflows/create_workflows.md` and `references/office-automation.md` explain what COM
218
186
  stores when you write these.
219
187
  - **Typed values.** Numbers as numbers, dates as dates, one number format per column.
220
188
  Invariant format codes (`#,##0`, `0.0%`, `"$"#,##0.00`) — never swap `.` and `,`.
221
189
  - **Reading someone else's workbook is read-only.** `references/read_only_qna.md`.
222
- - **Domain conventions** — finance, healthcare, marketing, scientific data — carry real
223
- meaning in their cells: `domain_guidance/`. Read the matching file before modelling in
224
- that area.
190
+ - **Domain conventions** — finance, healthcare, marketing, scientific data — read the
191
+ matching `domain_guidance/` file before modelling.
225
192
  - **Visual defaults** (headers, input fills, borders, tab colours, one font family):
226
193
  `style_guidelines.md`.
227
- - **Citations** for external data go next to the input table they support, not in a
228
- tab of their own.
194
+ - **Citations** for external data go next to the input table they support, not in a tab of
195
+ their own.
229
196
 
230
197
  ## Files in this skill
231
198
 
232
199
  | File | Use it when |
233
200
  | --- | --- |
234
- | `references/office-automation.md` | you need the COM object model: addressing, `Value2` vs `Formula`, colour encoding, locale, latency |
235
- | `references/read_only_qna.md` | answering a question about the open workbook without changing it |
201
+ | `references/office-automation.md` | COM object model: addressing, `Value2` vs `Formula`, colour, locale, latency |
202
+ | `references/read_only_qna.md` | answering a question without changing the workbook |
236
203
  | `style_guidelines.md` | the request involves how the sheet looks |
237
204
  | `workflows/create_workflows.md` | building a new sheet or workbook live |
238
205
  | `workflows/edit_workflows.md` | changing cells in a workbook the user already built |
@@ -1,7 +1,6 @@
1
1
  # Financial models
2
2
 
3
- Financial modelling has a short list of distinctions that decide whether a sheet is
4
- right, and a live edit makes each of them visible to a user who is watching.
3
+ A live edit makes every modelling distinction visible to a watching user.
5
4
 
6
5
  ## The distinctions that matter
7
6
 
@@ -11,76 +10,61 @@ right, and a live edit makes each of them visible to a user who is watching.
11
10
  | Payroll expense | Cash paid to employees — accruals, timing, employer costs |
12
11
  | Capex | Depreciation / amortisation — cash out once, expense over life |
13
12
  | Earnings | Cash flow — working capital, non-cash items, financing |
14
- | Budget | Forecast — one is a target, the other an expectation; never mix them silently |
13
+ | Budget | Forecast — a target vs an expectation; never mix them silently |
15
14
 
16
- Also, before typing a number: which fiscal calendar, which horizon (monthly / quarterly /
17
- annual), and which grain (total company, segment, product)? A number without those three
18
- is not a model input.
19
-
20
- Actuals and forecast must be visibly different (a divide, a label, a different fill). The
21
- reader has to know where history stops.
15
+ Establish fiscal calendar, horizon (monthly / quarterly / annual) and grain (company,
16
+ segment, product) before typing a number; without all three it is not a model input. Show
17
+ actuals and forecast apart (divide, label or fill) so the reader sees where history stops.
22
18
 
23
19
  ## Schedules
24
20
 
25
- Build a driver schedule per line, then a statement, then the output. Each step is a range
26
- the user can audit:
27
-
28
- - **Revenue**: volume × price, with mix if there are segments; recognition timing if
29
- contracts span periods. Do not model revenue as a straight growth percentage unless the
30
- user asked for that — it hides the drivers.
31
- - **Payroll**: headcount, FTE and paid FTE are three different numbers. Prorate hires and
32
- exits by month; do not divide an annual salary by 12 twice (an annual figure already
33
- contains the monthly rate); make the commission and employer-cost basis explicit.
34
- - **Opex**: units × rate, fixed amounts, or one-time costs — say which. A growing opex line
35
- needs a driver, not a percent of revenue, unless that is the stated policy.
36
- - **D&A**: cost, residual value, in-service date, useful life, convention. Reconcile gross
37
- asset and accumulated depreciation roll-forwards to the prior period.
38
- - **Statements**: retained earnings rolls from opening + net income − dividends; the
39
- cash-flow statement's ending cash equals the balance sheet's cash. If it does not, there
40
- is a plug, and a plug is a finding, not a fix.
41
-
42
- A worked unit check, done in the cells: actual salary cost $60,000 across 10 paid FTE is
43
- $6,000 per FTE; a forecast of $6,300 per FTE on 11 FTE gives $69,300 against $66,000 for
44
- the prior per-FTE rate — the difference is rate *and* headcount, and both drivers belong
45
- on separate rows. If either missing pay or zero FTE is in the source, the implied rate
46
- cannot be established; mark it unavailable, do not divide by zero and call it 0.
21
+ Build a driver schedule per line, then a statement, then the output.
22
+
23
+ - **Revenue**: volume × price; mix for segments; recognition timing for multi-period
24
+ contracts. No straight growth percentage unless the user asked.
25
+ - **Payroll**: headcount, FTE and paid FTE are three numbers. Prorate hires and exits by
26
+ month; never divide an annual salary by 12 twice; state commission and employer-cost basis.
27
+ - **Opex**: units × rate, fixed, or one-time — say which. A growing line needs a driver, not
28
+ a percent of revenue, unless that is stated policy.
29
+ - **D&A**: cost, residual value, in-service date, useful life, convention; reconcile
30
+ gross-asset and accumulated-depreciation roll-forwards to the prior period.
31
+ - **Statements**: retained earnings = opening + net income − dividends; cash-flow ending
32
+ cash = balance-sheet cash. A mismatch is a plug: report it, do not fix it.
33
+
34
+ Worked unit check, in the cells: $60,000 of salary over 10 paid FTE is $6,000 per FTE;
35
+ $6,300 per FTE × 11 is $69,300 against $66,000 at the prior rate — rate and headcount both
36
+ moved, so both need a row. Missing pay or zero FTE: implied rate unavailable; never divide
37
+ by zero into 0.
47
38
 
48
39
  ## Refreshes and merges
49
40
 
50
- A refresh merges complete periods on the business key (a date that exists in the calendar,
51
- a product code that exists in the master). Never append a partial period as if it were
52
- complete, and never let a merge drop a dimension silently — report rows that did not match.
41
+ Merge complete periods on the business key (calendar date, master product code). Never append
42
+ a partial period as complete; never drop a dimension silently — report unmatched rows.
53
43
 
54
44
  ## Variances and audit
55
45
 
56
- - Variances need an amount **and** a percent. When the base is zero or missing, the percent
57
- is unavailable — write `n.a.`, not `0%`.
46
+ - A variance needs an amount **and** a percent. Zero or missing base: write `n.a.`, not `0%`.
58
47
  - Check totals: parts sum to the whole, schedules tie to statements, the bridge closes to
59
- zero. Compare to two decimals, including `0.00`; a check that passes at 0.01 is not
60
- passing.
61
- - Failed checks: light red fill (`#FFC7CE`) with bold red text (`#9C0006`), neutral for
62
- passes. Missing or untested data is "unavailable", never "PASS".
48
+ zero; compare to two decimals including `0.00`; a check that passes at 0.01 is failing.
49
+ - Failed checks: `#FFC7CE` fill with bold `#9C0006` text; passes stay neutral. Missing or
50
+ untested data is "unavailable", never "PASS".
63
51
 
64
52
  ## Valuation, if it comes up
65
53
 
66
- - Build the method the user asked for. A DCF needs drivers, tax, D&A, capex, working
67
- capital, unlevered free cash flow, the discounting convention, a terminal value method
68
- and the enterprise-to-equity bridge — skipping two of these is not a shortcut, it is a
69
- wrong answer.
70
- - IRR/XIRR need cash flows with valid signs and dates; a series with no sign change has no
71
- IRR, and the function returning `#NUM!` is the correct answer to report.
72
- - Sensitivities the user asks for belong in a native what-if data table, not in a grid of
73
- hand-typed scenarios that will drift.
54
+ - A DCF needs drivers, tax, D&A, capex, working capital, unlevered free cash flow, the
55
+ discounting convention, a terminal-value method and the enterprise-to-equity bridge;
56
+ skipping two is a wrong answer, not a shortcut.
57
+ - IRR/XIRR need valid signs and dates; with no sign change there is no IRR, and `#NUM!` is
58
+ the answer to report.
59
+ - Sensitivities belong in a native what-if data table, not a grid of hand-typed scenarios.
74
60
 
75
61
  ## Doing it live
76
62
 
77
- - Read the workbook before you model: `info` for tabs and objects, then
78
- `read_range --formulas` across the rows you are extending. Match the existing anchoring
79
- (`$C$4` for a rate, `C$9` for a period header) and the existing aggregation style
80
- (`SUMIFS` over hand-rolled sums).
81
- - Add one driver row at a time, each with a formula you can point at, and verify after each
82
- block; a 200-cell scenario grid written blind is the expensive way to fail.
83
- - If the model has a check tab, extend the checks to cover your new rows. If it has none
84
- and the model is small, add one labelled verification row next to the output.
85
- - Never write a hard-coded total when a formula can tie it. And never "fix" an existing
86
- `#REF!` — report it.
63
+ - Read first: `info` for tabs and objects; `read_range --formulas` over the rows you will
64
+ extend; match existing anchoring (`$C$4` rate, `C$9` period header) and `SUMIFS`
65
+ aggregation.
66
+ - One driver row at a time, each with a formula you can point at; verify after each block. A
67
+ 200-cell scenario grid written blind is the expensive way to fail.
68
+ - Extend the check tab to cover new rows; on a small model with none, add one labelled
69
+ verification row beside the output.
70
+ - Never hard-code a total a formula can tie; never "fix" an existing `#REF!` — report it.
@@ -1,58 +1,52 @@
1
1
  # Healthcare
2
2
 
3
- Two kinds of workbook live in a health organisation, and they carry different rules:
3
+ Health organisations run two workbook kinds:
4
4
 
5
- - **Clinical and patient records**: appointments, encounters, observations, results.
6
- The source of truth is a clinical system; a workbook holds an extract.
7
- - **Administrative and financial work**: budgets, staffing, throughput, cost per case.
8
- Money follows `financial_models.md` even when the organisation is a hospital.
5
+ - **Clinical and patient records** — appointments, encounters, observations, results. The
6
+ clinical system is the source of truth; a workbook holds an extract.
7
+ - **Administrative and financial work** — budgets, staffing, throughput, cost per case. Money
8
+ follows `financial_models.md`, hospitals included.
9
9
 
10
- Most healthcare spreadsheet tasks are the second kind built on top of the first. Keep the
11
- extract and the analysis visibly separate.
10
+ Most tasks are the second kind built on the first. Keep extract and analysis visibly apart.
12
11
 
13
12
  ## Handling the raw extract
14
13
 
15
- - Put raw data on its own sheet or block, untouched, one table. Everything you compute
16
- lives *beside* it or in a separate prepared block — never by overwriting a measurement.
17
- - Descriptive names help the next reader: `Appointments_RawData` beats `Sheet2`;
18
- `Clinic KPI Dashboard` beats `Sheet5`.
19
- - Keep the source's definitions with the data: the period it covers, the extract date, the
20
- source system, the denominator used. Length of stay, readmission rate and utilisation
21
- are meaningless without them, and definitions differ between systems.
22
- - Preserve identifiers exactly as supplied (MRN formats vary), and keep dates as dates with
23
- one format down the column.
24
- - Units belong in the header (`Weight (kg)`, `Temperature (°C)`, `HbA1c (%)`, `Heart rate
25
- (bpm)`), not in the cells as text. A column of `"72 bpm"` strings cannot be averaged.
14
+ - Keep raw data untouched on its own sheet or block, as one table; compute beside it or in a
15
+ separate prepared block. Never overwrite a measurement.
16
+ - Name descriptively: `Appointments_RawData` beats `Sheet2`; `Clinic KPI Dashboard` beats
17
+ `Sheet5`.
18
+ - Keep the source's definitions with the data: period covered, extract date, source system,
19
+ denominator. Length of stay, readmission rate and utilisation are meaningless without them,
20
+ and systems define them differently.
21
+ - Preserve identifiers exactly (MRN formats vary); dates as dates, one format down the column.
22
+ - Units in the header (`Weight (kg)`, `Temperature (°C)`, `HbA1c (%)`, `Heart rate (bpm)`),
23
+ never cell text — `"72 bpm"` strings cannot be averaged.
26
24
 
27
25
  ## Building on it
28
26
 
29
- - Highlight the fields staff must complete (amber fill) and keep unused placeholders out.
30
- - If a threshold drives a flag, use one named cell for it (`BMI_threshold`) and reference
31
- it, so the cut-off is visible and changeable. A number buried in a formula is an
32
- invisible policy.
33
- - Flags come only from a stated source or protocol threshold, and keep the severity the
34
- source gives (normal / elevated / high), with a legend on the sheet. Do not invent
35
- clinical ranges, do not round a borderline value into a category.
36
- - A codebook (code → meaning, units, abbreviations) next to the data when the extract uses
37
- codes, or a legend when it uses abbreviations.
38
- - Keep a `Corrected value` column or an audit log for corrections. Never edit the original
39
- measurement in place; the original and the correction are both evidence.
27
+ - Highlight fields staff must complete (amber fill); no unused placeholders.
28
+ - For a threshold-driven flag, name one cell (`BMI_threshold`) and reference it, so the
29
+ cut-off is visible and changeable.
30
+ - Flags only from a stated source or protocol threshold, with its severity (normal / elevated
31
+ / high) and a sheet legend. Never invent clinical ranges; never round a borderline value
32
+ into a category.
33
+ - Codebook (code → meaning, units, abbreviations) beside coded data; legend for
34
+ abbreviations.
35
+ - `Corrected value` column or audit log; never edit the original measurement in place —
36
+ original and correction are both evidence.
40
37
 
41
38
  ## Consequences of getting it wrong
42
39
 
43
- Clinical arithmetic and clinical judgement are different things. Compute what the source
44
- supports; verify a critical calculation (dosing, risk score, threshold classification)
45
- against the authoritative definition when one is available, and if it is not available say
46
- so instead of asserting the number is right. Do not give clinical advice, and do not
47
- present a screening flag as a diagnosis.
40
+ Clinical arithmetic is not clinical judgement. Compute what the source supports; check a
41
+ critical calculation (dosing, risk score, threshold classification) against the authoritative
42
+ definition, and say when none exists rather than asserting the number. No clinical advice; a
43
+ screening flag is not a diagnosis.
48
44
 
49
45
  ## Doing it live
50
46
 
51
- - The user may have the extract open with their own formatting. Read before writing:
52
- `info` for the sheets and used ranges, `read_range --formulas --display` for the block
53
- you are extending.
54
- - Add derived columns to the right of the raw block with a clear header, or to a separate
55
- prepared area; never insert a column into the middle of an extract that other formulas
56
- or a pivot already reference.
57
- - After writing, verify with `read_range --formulas` and check the `errors` array — a
58
- healthcare sheet with a `#DIV/0!` in a rate column is a report that will be misread.
47
+ - The extract may be open with the user's formatting. Read first: `info` for sheets and used
48
+ ranges; `read_range --formulas --display` for the block you will extend.
49
+ - Add derived columns right of the raw block with a clear header, or in a separate prepared
50
+ area; never insert a column into an extract that formulas or a pivot reference.
51
+ - After writing, verify with `read_range --formulas` and check `errors` — a `#DIV/0!` in a
52
+ rate column becomes a misread report.