iwork-studio 2.3.0__tar.gz → 2.4.0__tar.gz

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 (58) hide show
  1. {iwork_studio-2.3.0/src/iwork_studio.egg-info → iwork_studio-2.4.0}/PKG-INFO +46 -19
  2. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/README.md +45 -18
  3. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/pyproject.toml +1 -1
  4. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/__init__.py +1 -1
  5. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/design.py +301 -14
  6. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/exporter.py +22 -1
  7. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/keynote_deck.py +130 -9
  8. iwork_studio-2.4.0/src/iwork_studio/keynote_table.py +303 -0
  9. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/keynote_theme.py +24 -4
  10. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/mcp_server.py +166 -2
  11. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/pdf.py +26 -1
  12. iwork_studio-2.4.0/src/iwork_studio/review.py +250 -0
  13. {iwork_studio-2.3.0 → iwork_studio-2.4.0/src/iwork_studio.egg-info}/PKG-INFO +46 -19
  14. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio.egg-info/SOURCES.txt +4 -0
  15. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_design.py +134 -0
  16. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_exporter.py +22 -2
  17. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_keynote_deck.py +94 -0
  18. iwork_studio-2.4.0/tests/test_keynote_table.py +286 -0
  19. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_mcp_server.py +20 -1
  20. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_packaging.py +5 -0
  21. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_preview.py +2 -1
  22. iwork_studio-2.4.0/tests/test_review.py +138 -0
  23. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/LICENSE +0 -0
  24. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/THIRD_PARTY_NOTICES.md +0 -0
  25. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/setup.cfg +0 -0
  26. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/app_ops.py +0 -0
  27. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/apps.py +0 -0
  28. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/backups.py +0 -0
  29. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/format_check.py +0 -0
  30. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/helpers.py +0 -0
  31. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/installer.py +0 -0
  32. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/keynote_applescript.py +0 -0
  33. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/keynote_io.py +0 -0
  34. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/keynote_slides.py +0 -0
  35. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/numbers_format.py +0 -0
  36. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/numbers_io.py +0 -0
  37. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/numbers_structure.py +0 -0
  38. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/pages_io.py +0 -0
  39. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/preview.py +0 -0
  40. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio/render_verify.py +0 -0
  41. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio.egg-info/dependency_links.txt +0 -0
  42. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio.egg-info/entry_points.txt +0 -0
  43. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio.egg-info/requires.txt +0 -0
  44. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/src/iwork_studio.egg-info/top_level.txt +0 -0
  45. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_app_ops.py +0 -0
  46. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_apps.py +0 -0
  47. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_backups.py +0 -0
  48. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_format_check.py +0 -0
  49. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_installer.py +0 -0
  50. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_keynote_slides.py +0 -0
  51. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_keynote_theme.py +0 -0
  52. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_keynote_writer.py +0 -0
  53. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_numbers_format.py +0 -0
  54. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_numbers_structure.py +0 -0
  55. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_numbers_writer.py +0 -0
  56. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_pages_writer.py +0 -0
  57. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_render_route.py +0 -0
  58. {iwork_studio-2.3.0 → iwork_studio-2.4.0}/tests/test_value_fidelity.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iwork-studio
3
- Version: 2.3.0
3
+ Version: 2.4.0
4
4
  Summary: Create, edit, design and export Apple Numbers, Keynote and Pages files from any AI agent: verified, reversible, Arabic-safe. MCP server + Python library + agent skill.
5
5
  Author: iWork Studio contributors
6
6
  License-Expression: MIT
@@ -45,7 +45,7 @@ Dynamic: license-file
45
45
  [![Version](https://img.shields.io/badge/version-2.3.0-1a7f79)](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
46
46
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Arkanji/iwork-studio/tree/main/LICENSE)
47
47
  [![iWork](https://img.shields.io/badge/iWork-classic%20%2B%20Creator%20Studio-black?logo=apple&logoColor=white)](#what-it-can-do)
48
- [![MCP server](https://img.shields.io/badge/MCP-58%20tools-8A2BE2)](#all-58-tools)
48
+ [![MCP server](https://img.shields.io/badge/MCP-64%20tools-8A2BE2)](#all-64-tools)
49
49
  [![Arabic safe](https://img.shields.io/badge/Arabic%2FRTL-exact%20round--trips-informational)](#arabic--rtl)
50
50
  [![Undo](https://img.shields.io/badge/every%20write-backed%20up%20%2B%20undoable-success)](#the-safety-model)
51
51
 
@@ -54,7 +54,7 @@ Dynamic: license-file
54
54
  Create, edit, format, theme and export **Numbers**, **Keynote** and **Pages** files from Claude or any AI agent.<br>
55
55
  Every write is backed up, checked and swapped in atomically, and any change can be undone with one call.
56
56
 
57
- [**Install**](#install) · [What it can do](#what-it-can-do) · [Safety](#the-safety-model) · [All 58 tools](#all-58-tools) · [For AI agents](#for-ai-agents) · [Changelog](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
57
+ [**Install**](#install) · [What it can do](#what-it-can-do) · [Safety](#the-safety-model) · [All 64 tools](#all-64-tools) · [For AI agents](#for-ai-agents) · [Changelog](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
58
58
 
59
59
  <br>
60
60
 
@@ -74,7 +74,8 @@ Every write is backed up, checked and swapped in atomically, and any change can
74
74
  |---|---|
75
75
  | **Claude desktop app, one click** (Mac) | Download `iwork-studio-<version>.mcpb` from the [latest release](https://github.com/Arkanji/iwork-studio/releases/latest), double-click it, pick the folders it may use |
76
76
  | **Claude desktop app** (Mac, from Terminal) | Paste in Terminal: `curl -LsSf https://raw.githubusercontent.com/Arkanji/iwork-studio/main/install.sh \| sh`, then quit Claude (Cmd-Q) and reopen |
77
- | **Claude Code** | `claude mcp add iwork-studio -- uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp` |
77
+ | **Claude Code, as a plugin** (tools + skill) | `/plugin marketplace add Arkanji/iwork-studio`, then `/plugin install iwork-studio@iwork-studio` |
78
+ | **Claude Code, tools only** | `claude mcp add iwork-studio -- uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp` |
78
79
  | **Cursor, VS Code, Codex, any MCP client** | `uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp config`, then paste the printed JSON into the client's MCP settings. Also listed in the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.Arkanji/iwork-studio` |
79
80
 
80
81
  That's it. The installer sets up [`uv`](https://docs.astral.sh/uv/) if needed, and uv brings its own Python.
@@ -90,6 +91,12 @@ That's it. The installer sets up [`uv`](https://docs.astral.sh/uv/) if needed, a
90
91
 
91
92
  > *"Build a 6-slide pitch deck on programmable gift cards in the midnight kit, with speaker notes, and export it to PowerPoint."*
92
93
  >
94
+ > *"Turn sales.numbers into a board deck: chart the quarters, a table of the top regions, in our Resal kit."*
95
+ >
96
+ > *"Take the fonts and colours from brand.key and save them as our Resal kit."*
97
+ >
98
+ > *"Review pitch.key and fix anything that overflows or is too small to read."*
99
+ >
93
100
  > *"Make budget.numbers look professional with the banking kit — and show me a preview first."*
94
101
  >
95
102
  > *"Turn sales.csv into a Numbers file, make the header bold on a teal fill, show column B as SAR with two decimals, and add a total row."*
@@ -113,9 +120,10 @@ That's it. The installer sets up [`uv`](https://docs.astral.sh/uv/) if needed, a
113
120
  | | **Numbers** | **Keynote** | **Pages** |
114
121
  |---|---|---|---|
115
122
  | **Read** | Every sheet, table, cell, formula and format | Every slide's text, notes, layout, theme, styling and charts | Body text, placeholders and tables |
116
- | **Create** | From data or CSV ⚡ · from a built-in template · from your own file | **A designed deck from an outline** · from a built-in theme · from your own deck | From a built-in template · from your own file |
117
- | **Edit content** | Cells ⚡ · formulas · recalculate · insert/delete rows and columns ⚡ · add tables and sheets ⚡ · sort | Find/replace across the deck ⚡ · slide titles and bullets · add, duplicate, delete, move, hide slides · presenter notes · images · charts | Replace text everywhere · replace the body · fill placeholders · table cells (text, numbers, formulas) |
118
- | **Design** | Design kits ⚡ · fonts, colours, fill, alignment, wrap ⚡ · currency, %, dates, decimals ⚡ · borders ⚡ · widths and heights ⚡ · headers ⚡ · merges ⚡ | Design kits · theme · slide layout · text font, size and colour · transitions | — |
123
+ | **Create** | From data or CSV ⚡ · from a built-in template · from your own file | **A designed deck from an outline, with chart and table slides** (straight from a Numbers table) · from a built-in theme · from your own deck | From a built-in template · from your own file |
124
+ | **Edit content** | Cells ⚡ · formulas · recalculate · insert/delete rows and columns ⚡ · add tables and sheets ⚡ · sort | Find/replace across the deck ⚡ · slide titles and bullets · add, duplicate, delete, move, hide slides · presenter notes · images · charts · tables | Replace text everywhere · replace the body · fill placeholders · table cells (text, numbers, formulas) |
125
+ | **Design** | Design kits ⚡ · your brand kit ⚡ · fonts, colours, fill, alignment, wrap ⚡ · currency, %, dates, decimals ⚡ · borders ⚡ · widths and heights ⚡ · headers ⚡ · merges ⚡ | Design kits · your brand kit · theme · slide layout · text font, size and colour · styled tables · transitions | — |
126
+ | **Review** | | **Design review** of what Keynote draws: text off the slide or past its box, text Keynote had to shrink, overlaps, small text, crowded slides · any slide as an image | |
119
127
  | **Export** | PDF · Excel · CSV | PDF · PowerPoint · images · movie | PDF · Word · EPUB · text · RTF |
120
128
  | **Present** | | Start, stop, next, previous | |
121
129
 
@@ -131,7 +139,7 @@ On purpose, so it never breaks a file:
131
139
  - **Charts in Numbers and Pages** can't be created: Apple doesn't make them scriptable. Keynote charts can be added.
132
140
  - **Pages** is limited to text and existing tables: replace, set body, placeholders and table cells. New tables can't be created (Pages 15 doesn't script it), and page-layout documents, like most letter templates, have no body text. There is no Pages file format parser anywhere, so it doesn't fake one.
133
141
  - **Formulas and row shifts**: in a table that has formulas, rows and columns can only be appended without the app. Inserting in the middle would leave references pointing at the wrong cells.
134
- - **Not scriptable by Apple**, so not offered: Numbers table styles, Keynote shape fill and text alignment, editing a theme's master slides. Page margins and page setup are planned.
142
+ - **Not scriptable by Apple**, so not offered: Numbers table styles, Keynote shape fill and text alignment, deleting a Keynote table, editing a theme's master slides. Page margins and page setup are planned.
135
143
 
136
144
  ## Designed, not just edited
137
145
 
@@ -148,6 +156,12 @@ Six **design kits** turn a plain deck or table into something you'd present: a f
148
156
 
149
157
  Build with one (`keynote_build_deck(..., kit="midnight")`), restyle anything (`keynote_apply_design`, `numbers_apply_design`), or bring your brand as colours and fonts — contrast is checked. Agents also get a [design guide](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/design-guide.md): one idea per slide, titles that state the takeaway, right-aligned numbers, restrained colour.
150
158
 
159
+ **Your brand, once.** Point `iwork_extract_design_kit` at a deck or table that already has your look: it reads the fonts (Latin and Arabic) and colours, and saves them as a named kit you can use anywhere a kit goes. Or save your colours and fonts directly with `iwork_save_design_kit`.
160
+
161
+ **Numbers on slides.** A slide in `keynote_build_deck` can carry a chart or a table, from data or straight from a Numbers table: the header row gives the columns, the first column the rows. Tables get the kit's header band, fonts, banding and right-aligned numbers, and every cell is read back.
162
+
163
+ **It checks its own work.** `keynote_review_deck` renders the deck through Keynote and compares every drawn line with its text box: text off the slide or running past its box is an error; text Keynote had to shrink to fit, overlapping boxes, text under 18 pt and crowded slides are warnings. `keynote_slide_image` hands a slide back as an image, so an agent can look before it says "done".
164
+
151
165
  ## The safety model
152
166
 
153
167
  An iWork app will happily say "saved" about a file it just broke. Nothing here trusts "saved".
@@ -158,7 +172,7 @@ backup → change a scratch copy → re-open it and compare → atomic swap
158
172
  ```
159
173
 
160
174
  - **Backup first**, versioned, next to the file in `<file>.backups/`.
161
- - **Re-read and compared**: exactly the requested change happened, and nothing else did. A cell edit checks every other cell. A row insert checks every cell at its new position. A slide op checks every other slide. A sort checks it's a pure reorder. On files with charts, every chart is counted before and after. An export is read back with a second, independent tool.
175
+ - **Re-read and compared**: exactly the requested change happened, and nothing else did. A cell edit checks every other cell. A row insert checks every cell at its new position. A slide op checks every other slide. A sort checks it's a pure reorder. On files with charts, every chart is counted before and after; on decks with tables, every table's cells are compared. An export is read back with a second, independent tool.
162
176
  - **Atomic swap**: the file is replaced in one step, so a crash can't leave half a file.
163
177
  - **The app's "ok" is never trusted.** App-driven writes are re-read from disk, and a write that "succeeded" but didn't land is rolled back.
164
178
  - **Undo is one call**: `iwork_list_backups` → `iwork_restore_backup`. The restore backs up the current version first, so undo can be undone too.
@@ -173,12 +187,12 @@ backup → change a scratch copy → re-open it and compare → atomic swap
173
187
  - Values are kept as typed: Arabic-Indic digits (`١٢٣`), `"$1,234.56"` and `=…` text stay text. Pass a real number when you want a number.
174
188
  - When checking a rendered PDF, assert **one** Arabic word. PDF text layers reorder multi-word RTL text.
175
189
 
176
- ## All 58 tools
190
+ ## All 64 tools
177
191
 
178
192
  Writes are marked destructive and reads read-only, so clients can ask before writing. Every write that changes an existing file takes `dry_run=true` for a preview.
179
193
 
180
194
  <details open>
181
- <summary><b>Any file</b> (14)</summary>
195
+ <summary><b>Any file</b> (17)</summary>
182
196
 
183
197
  | Tool | What it does |
184
198
  |---|---|
@@ -188,7 +202,9 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
188
202
  | `iwork_metadata` · `iwork_thumbnail` | Template, app builds, format version, slide count · the stored preview image |
189
203
  | `iwork_create` · `iwork_create_from_template` | New file from Apple's built-in templates · copy of your own file |
190
204
  | `iwork_list_templates` | Built-in templates (Numbers, Pages) and themes (Keynote) |
191
- | `iwork_list_design_kits` | Design kits: fonts, palettes, type scale |
205
+ | `iwork_list_design_kits` | Design kits: fonts, palettes, type scale — presets and your saved kits |
206
+ | `iwork_extract_design_kit` | A kit from your own deck or table: its fonts and colours; save it by name |
207
+ | `iwork_save_design_kit` · `iwork_delete_design_kit` | Keep your brand kit by name · remove one |
192
208
  | `iwork_export` | PDF, Excel, CSV, Word, EPUB, text, RTF, PowerPoint, slide images, movie; optional password |
193
209
  | `iwork_verify_render` · `iwork_verify_format` | Rendered PDF shows this text · with this font, size, colour, page size |
194
210
  | `iwork_list_backups` · `iwork_restore_backup` | Undo |
@@ -216,11 +232,13 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
216
232
  </details>
217
233
 
218
234
  <details>
219
- <summary><b>Keynote</b> (20)</summary>
235
+ <summary><b>Keynote</b> (23)</summary>
220
236
 
221
237
  | Tool | What it does |
222
238
  |---|---|
223
- | `keynote_build_deck` | A new deck from an outline: titles, bullets, notes, images, transition, design kit |
239
+ | `keynote_build_deck` | A new deck from an outline: titles, bullets, notes, images, chart and table slides, transition, design kit |
240
+ | `keynote_review_deck` | Design review of the rendered deck: off-slide and overflowing text, overlaps, small text, crowded slides |
241
+ | `keynote_slide_image` | One slide as an image, to look at |
224
242
  | `keynote_set_slide_text` | Fill a slide's title and body |
225
243
  | `keynote_apply_design` | Restyle every slide from a design kit |
226
244
  | `keynote_replace_text` | Find/replace on every slide, formatting untouched |
@@ -232,6 +250,7 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
232
250
  | `keynote_set_transition` | Effect, duration, delay, auto-advance |
233
251
  | `keynote_add_image` | Place an image on a slide |
234
252
  | `keynote_add_chart` | Add a bar, line, area, pie or scatter chart from data |
253
+ | `keynote_add_table` | Add a table, styled from a design kit; every cell is read back |
235
254
  | `keynote_slideshow` | Start, stop, next, previous |
236
255
 
237
256
  </details>
@@ -250,6 +269,8 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
250
269
 
251
270
  Keynote slide, theme, transition and image tools refuse a deck that's open in Keynote (they never close a window that may hold unsaved work). To hide them all: `IWORK_STUDIO_DISABLE_SLIDE_OPS=1`.
252
271
 
272
+ **Prompts.** Clients that show MCP prompts get four ready-made workflows: *Pitch deck from an outline*, *Report deck from a Numbers table*, *Restyle with my brand* and *Make this table look designed*. Each writes to the design rules, builds in one call, previews before restyling, and runs the design review before it calls the job done.
273
+
253
274
  ## For AI agents
254
275
 
255
276
  - **[`AGENTS.md`](https://github.com/Arkanji/iwork-studio/blob/main/AGENTS.md)**: setup and usage rules for any agent (Codex, Cursor, Copilot, Gemini; Claude Code reads it via `CLAUDE.md`).
@@ -268,10 +289,14 @@ pip install iwork-studio # Python 3.12
268
289
  ```python
269
290
  from iwork_studio import numbers_structure, numbers_format, numbers_io, keynote_io, keynote_slides, exporter, backups
270
291
 
271
- from iwork_studio import keynote_deck, design
292
+ from iwork_studio import keynote_deck, design, review
272
293
 
273
294
  keynote_deck.build_deck("pitch.key", [{"title": "رسال", "body": "Programmable value"},
274
- {"title": "Why now", "body": ["Trust", "Access"]}], kit="midnight") # macOS + Keynote
295
+ {"title": "Why now", "body": ["Trust", "Access"]},
296
+ {"title": "Riyadh leads growth", "chart": {"type": "bar", "from": "sales.numbers"}}],
297
+ kit="midnight") # macOS + Keynote
298
+ review.review_deck("pitch.key")["findings"] # macOS + Keynote
299
+ design.extract_kit("brand.numbers", name="Resal", save=True)
275
300
  numbers_structure.import_csv("sales.csv", "sales.numbers")
276
301
  design.apply_to_numbers("sales.numbers", "banking")
277
302
  numbers_format.set_cell_style("sales.numbers", "A1:D1", bold=True, fill_color="#1A7F79", font_color="#FFFFFF")
@@ -306,6 +331,7 @@ backups.restore_backup("sales.numbers", backups.list_backups("sales.numbers")[0]
306
331
  18. **Numbers doesn't recalculate formulas when it opens a file changed without it**: a total keeps its old result. Edits made without the app say so, and `numbers_recalculate` has Numbers recompute every formula.
307
332
  19. **A rounding library used by numbers-parser wipes every warning filter in the process** on each save. It's wrapped so it stays quiet without touching anyone else's settings.
308
333
  20. **Don't keep the repo in iCloud Drive.** Sync creates "main 2" copies inside `.git`.
334
+ 21. **Keynote creates tables only one way**: `tell slide n to make new table` works, while `make new table at end of tables of slide n` and deleting a table fail with `-10000`. A failed table add is undone by restoring the backup.
309
335
 
310
336
  More, each with its status: [`jxa-traps.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/jxa-traps.md) (including traps borrowed from [reichenbach/iwork_mcp](https://github.com/reichenbach/iwork_mcp)).
311
337
 
@@ -322,10 +348,11 @@ MCP server · CLI scripts · skill → thin wrappers over t
322
348
 
323
349
  ```
324
350
  src/iwork_studio/ numbers_io · numbers_format · numbers_structure · keynote_io · keynote_slides · keynote_theme
325
- keynote_deck · design · preview · pages_io · app_ops · exporter · helpers · format_check
326
- render_verify · backups · apps · mcp_server
351
+ keynote_deck · keynote_table · design · review · preview · pages_io · app_ops · exporter
352
+ helpers · format_check · render_verify · pdf · backups · apps · mcp_server
327
353
  mcpb/ Claude Desktop extension manifest (scripts/build_mcpb.sh builds the .mcpb)
328
- skill-pack/ SKILL.md · CLI scripts · references (capabilities, traps, pins)
354
+ skill-pack/ SKILL.md · CLI scripts · references (capabilities, traps, pins); also the Claude Code plugin
355
+ .claude-plugin/ plugin marketplace (one plugin: skill-pack/)
329
356
  tests/ headless suite (CI) · `pytest -m aqua` = live suite for a Mac with iWork
330
357
  install.sh one-line setup for the Claude desktop app
331
358
  ```
@@ -8,7 +8,7 @@
8
8
  [![Version](https://img.shields.io/badge/version-2.3.0-1a7f79)](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
9
9
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Arkanji/iwork-studio/tree/main/LICENSE)
10
10
  [![iWork](https://img.shields.io/badge/iWork-classic%20%2B%20Creator%20Studio-black?logo=apple&logoColor=white)](#what-it-can-do)
11
- [![MCP server](https://img.shields.io/badge/MCP-58%20tools-8A2BE2)](#all-58-tools)
11
+ [![MCP server](https://img.shields.io/badge/MCP-64%20tools-8A2BE2)](#all-64-tools)
12
12
  [![Arabic safe](https://img.shields.io/badge/Arabic%2FRTL-exact%20round--trips-informational)](#arabic--rtl)
13
13
  [![Undo](https://img.shields.io/badge/every%20write-backed%20up%20%2B%20undoable-success)](#the-safety-model)
14
14
 
@@ -17,7 +17,7 @@
17
17
  Create, edit, format, theme and export **Numbers**, **Keynote** and **Pages** files from Claude or any AI agent.<br>
18
18
  Every write is backed up, checked and swapped in atomically, and any change can be undone with one call.
19
19
 
20
- [**Install**](#install) · [What it can do](#what-it-can-do) · [Safety](#the-safety-model) · [All 58 tools](#all-58-tools) · [For AI agents](#for-ai-agents) · [Changelog](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
20
+ [**Install**](#install) · [What it can do](#what-it-can-do) · [Safety](#the-safety-model) · [All 64 tools](#all-64-tools) · [For AI agents](#for-ai-agents) · [Changelog](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
21
21
 
22
22
  <br>
23
23
 
@@ -37,7 +37,8 @@ Every write is backed up, checked and swapped in atomically, and any change can
37
37
  |---|---|
38
38
  | **Claude desktop app, one click** (Mac) | Download `iwork-studio-<version>.mcpb` from the [latest release](https://github.com/Arkanji/iwork-studio/releases/latest), double-click it, pick the folders it may use |
39
39
  | **Claude desktop app** (Mac, from Terminal) | Paste in Terminal: `curl -LsSf https://raw.githubusercontent.com/Arkanji/iwork-studio/main/install.sh \| sh`, then quit Claude (Cmd-Q) and reopen |
40
- | **Claude Code** | `claude mcp add iwork-studio -- uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp` |
40
+ | **Claude Code, as a plugin** (tools + skill) | `/plugin marketplace add Arkanji/iwork-studio`, then `/plugin install iwork-studio@iwork-studio` |
41
+ | **Claude Code, tools only** | `claude mcp add iwork-studio -- uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp` |
41
42
  | **Cursor, VS Code, Codex, any MCP client** | `uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp config`, then paste the printed JSON into the client's MCP settings. Also listed in the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.Arkanji/iwork-studio` |
42
43
 
43
44
  That's it. The installer sets up [`uv`](https://docs.astral.sh/uv/) if needed, and uv brings its own Python.
@@ -53,6 +54,12 @@ That's it. The installer sets up [`uv`](https://docs.astral.sh/uv/) if needed, a
53
54
 
54
55
  > *"Build a 6-slide pitch deck on programmable gift cards in the midnight kit, with speaker notes, and export it to PowerPoint."*
55
56
  >
57
+ > *"Turn sales.numbers into a board deck: chart the quarters, a table of the top regions, in our Resal kit."*
58
+ >
59
+ > *"Take the fonts and colours from brand.key and save them as our Resal kit."*
60
+ >
61
+ > *"Review pitch.key and fix anything that overflows or is too small to read."*
62
+ >
56
63
  > *"Make budget.numbers look professional with the banking kit — and show me a preview first."*
57
64
  >
58
65
  > *"Turn sales.csv into a Numbers file, make the header bold on a teal fill, show column B as SAR with two decimals, and add a total row."*
@@ -76,9 +83,10 @@ That's it. The installer sets up [`uv`](https://docs.astral.sh/uv/) if needed, a
76
83
  | | **Numbers** | **Keynote** | **Pages** |
77
84
  |---|---|---|---|
78
85
  | **Read** | Every sheet, table, cell, formula and format | Every slide's text, notes, layout, theme, styling and charts | Body text, placeholders and tables |
79
- | **Create** | From data or CSV ⚡ · from a built-in template · from your own file | **A designed deck from an outline** · from a built-in theme · from your own deck | From a built-in template · from your own file |
80
- | **Edit content** | Cells ⚡ · formulas · recalculate · insert/delete rows and columns ⚡ · add tables and sheets ⚡ · sort | Find/replace across the deck ⚡ · slide titles and bullets · add, duplicate, delete, move, hide slides · presenter notes · images · charts | Replace text everywhere · replace the body · fill placeholders · table cells (text, numbers, formulas) |
81
- | **Design** | Design kits ⚡ · fonts, colours, fill, alignment, wrap ⚡ · currency, %, dates, decimals ⚡ · borders ⚡ · widths and heights ⚡ · headers ⚡ · merges ⚡ | Design kits · theme · slide layout · text font, size and colour · transitions | — |
86
+ | **Create** | From data or CSV ⚡ · from a built-in template · from your own file | **A designed deck from an outline, with chart and table slides** (straight from a Numbers table) · from a built-in theme · from your own deck | From a built-in template · from your own file |
87
+ | **Edit content** | Cells ⚡ · formulas · recalculate · insert/delete rows and columns ⚡ · add tables and sheets ⚡ · sort | Find/replace across the deck ⚡ · slide titles and bullets · add, duplicate, delete, move, hide slides · presenter notes · images · charts · tables | Replace text everywhere · replace the body · fill placeholders · table cells (text, numbers, formulas) |
88
+ | **Design** | Design kits ⚡ · your brand kit ⚡ · fonts, colours, fill, alignment, wrap ⚡ · currency, %, dates, decimals ⚡ · borders ⚡ · widths and heights ⚡ · headers ⚡ · merges ⚡ | Design kits · your brand kit · theme · slide layout · text font, size and colour · styled tables · transitions | — |
89
+ | **Review** | | **Design review** of what Keynote draws: text off the slide or past its box, text Keynote had to shrink, overlaps, small text, crowded slides · any slide as an image | |
82
90
  | **Export** | PDF · Excel · CSV | PDF · PowerPoint · images · movie | PDF · Word · EPUB · text · RTF |
83
91
  | **Present** | | Start, stop, next, previous | |
84
92
 
@@ -94,7 +102,7 @@ On purpose, so it never breaks a file:
94
102
  - **Charts in Numbers and Pages** can't be created: Apple doesn't make them scriptable. Keynote charts can be added.
95
103
  - **Pages** is limited to text and existing tables: replace, set body, placeholders and table cells. New tables can't be created (Pages 15 doesn't script it), and page-layout documents, like most letter templates, have no body text. There is no Pages file format parser anywhere, so it doesn't fake one.
96
104
  - **Formulas and row shifts**: in a table that has formulas, rows and columns can only be appended without the app. Inserting in the middle would leave references pointing at the wrong cells.
97
- - **Not scriptable by Apple**, so not offered: Numbers table styles, Keynote shape fill and text alignment, editing a theme's master slides. Page margins and page setup are planned.
105
+ - **Not scriptable by Apple**, so not offered: Numbers table styles, Keynote shape fill and text alignment, deleting a Keynote table, editing a theme's master slides. Page margins and page setup are planned.
98
106
 
99
107
  ## Designed, not just edited
100
108
 
@@ -111,6 +119,12 @@ Six **design kits** turn a plain deck or table into something you'd present: a f
111
119
 
112
120
  Build with one (`keynote_build_deck(..., kit="midnight")`), restyle anything (`keynote_apply_design`, `numbers_apply_design`), or bring your brand as colours and fonts — contrast is checked. Agents also get a [design guide](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/design-guide.md): one idea per slide, titles that state the takeaway, right-aligned numbers, restrained colour.
113
121
 
122
+ **Your brand, once.** Point `iwork_extract_design_kit` at a deck or table that already has your look: it reads the fonts (Latin and Arabic) and colours, and saves them as a named kit you can use anywhere a kit goes. Or save your colours and fonts directly with `iwork_save_design_kit`.
123
+
124
+ **Numbers on slides.** A slide in `keynote_build_deck` can carry a chart or a table, from data or straight from a Numbers table: the header row gives the columns, the first column the rows. Tables get the kit's header band, fonts, banding and right-aligned numbers, and every cell is read back.
125
+
126
+ **It checks its own work.** `keynote_review_deck` renders the deck through Keynote and compares every drawn line with its text box: text off the slide or running past its box is an error; text Keynote had to shrink to fit, overlapping boxes, text under 18 pt and crowded slides are warnings. `keynote_slide_image` hands a slide back as an image, so an agent can look before it says "done".
127
+
114
128
  ## The safety model
115
129
 
116
130
  An iWork app will happily say "saved" about a file it just broke. Nothing here trusts "saved".
@@ -121,7 +135,7 @@ backup → change a scratch copy → re-open it and compare → atomic swap
121
135
  ```
122
136
 
123
137
  - **Backup first**, versioned, next to the file in `<file>.backups/`.
124
- - **Re-read and compared**: exactly the requested change happened, and nothing else did. A cell edit checks every other cell. A row insert checks every cell at its new position. A slide op checks every other slide. A sort checks it's a pure reorder. On files with charts, every chart is counted before and after. An export is read back with a second, independent tool.
138
+ - **Re-read and compared**: exactly the requested change happened, and nothing else did. A cell edit checks every other cell. A row insert checks every cell at its new position. A slide op checks every other slide. A sort checks it's a pure reorder. On files with charts, every chart is counted before and after; on decks with tables, every table's cells are compared. An export is read back with a second, independent tool.
125
139
  - **Atomic swap**: the file is replaced in one step, so a crash can't leave half a file.
126
140
  - **The app's "ok" is never trusted.** App-driven writes are re-read from disk, and a write that "succeeded" but didn't land is rolled back.
127
141
  - **Undo is one call**: `iwork_list_backups` → `iwork_restore_backup`. The restore backs up the current version first, so undo can be undone too.
@@ -136,12 +150,12 @@ backup → change a scratch copy → re-open it and compare → atomic swap
136
150
  - Values are kept as typed: Arabic-Indic digits (`١٢٣`), `"$1,234.56"` and `=…` text stay text. Pass a real number when you want a number.
137
151
  - When checking a rendered PDF, assert **one** Arabic word. PDF text layers reorder multi-word RTL text.
138
152
 
139
- ## All 58 tools
153
+ ## All 64 tools
140
154
 
141
155
  Writes are marked destructive and reads read-only, so clients can ask before writing. Every write that changes an existing file takes `dry_run=true` for a preview.
142
156
 
143
157
  <details open>
144
- <summary><b>Any file</b> (14)</summary>
158
+ <summary><b>Any file</b> (17)</summary>
145
159
 
146
160
  | Tool | What it does |
147
161
  |---|---|
@@ -151,7 +165,9 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
151
165
  | `iwork_metadata` · `iwork_thumbnail` | Template, app builds, format version, slide count · the stored preview image |
152
166
  | `iwork_create` · `iwork_create_from_template` | New file from Apple's built-in templates · copy of your own file |
153
167
  | `iwork_list_templates` | Built-in templates (Numbers, Pages) and themes (Keynote) |
154
- | `iwork_list_design_kits` | Design kits: fonts, palettes, type scale |
168
+ | `iwork_list_design_kits` | Design kits: fonts, palettes, type scale — presets and your saved kits |
169
+ | `iwork_extract_design_kit` | A kit from your own deck or table: its fonts and colours; save it by name |
170
+ | `iwork_save_design_kit` · `iwork_delete_design_kit` | Keep your brand kit by name · remove one |
155
171
  | `iwork_export` | PDF, Excel, CSV, Word, EPUB, text, RTF, PowerPoint, slide images, movie; optional password |
156
172
  | `iwork_verify_render` · `iwork_verify_format` | Rendered PDF shows this text · with this font, size, colour, page size |
157
173
  | `iwork_list_backups` · `iwork_restore_backup` | Undo |
@@ -179,11 +195,13 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
179
195
  </details>
180
196
 
181
197
  <details>
182
- <summary><b>Keynote</b> (20)</summary>
198
+ <summary><b>Keynote</b> (23)</summary>
183
199
 
184
200
  | Tool | What it does |
185
201
  |---|---|
186
- | `keynote_build_deck` | A new deck from an outline: titles, bullets, notes, images, transition, design kit |
202
+ | `keynote_build_deck` | A new deck from an outline: titles, bullets, notes, images, chart and table slides, transition, design kit |
203
+ | `keynote_review_deck` | Design review of the rendered deck: off-slide and overflowing text, overlaps, small text, crowded slides |
204
+ | `keynote_slide_image` | One slide as an image, to look at |
187
205
  | `keynote_set_slide_text` | Fill a slide's title and body |
188
206
  | `keynote_apply_design` | Restyle every slide from a design kit |
189
207
  | `keynote_replace_text` | Find/replace on every slide, formatting untouched |
@@ -195,6 +213,7 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
195
213
  | `keynote_set_transition` | Effect, duration, delay, auto-advance |
196
214
  | `keynote_add_image` | Place an image on a slide |
197
215
  | `keynote_add_chart` | Add a bar, line, area, pie or scatter chart from data |
216
+ | `keynote_add_table` | Add a table, styled from a design kit; every cell is read back |
198
217
  | `keynote_slideshow` | Start, stop, next, previous |
199
218
 
200
219
  </details>
@@ -213,6 +232,8 @@ Writes are marked destructive and reads read-only, so clients can ask before wri
213
232
 
214
233
  Keynote slide, theme, transition and image tools refuse a deck that's open in Keynote (they never close a window that may hold unsaved work). To hide them all: `IWORK_STUDIO_DISABLE_SLIDE_OPS=1`.
215
234
 
235
+ **Prompts.** Clients that show MCP prompts get four ready-made workflows: *Pitch deck from an outline*, *Report deck from a Numbers table*, *Restyle with my brand* and *Make this table look designed*. Each writes to the design rules, builds in one call, previews before restyling, and runs the design review before it calls the job done.
236
+
216
237
  ## For AI agents
217
238
 
218
239
  - **[`AGENTS.md`](https://github.com/Arkanji/iwork-studio/blob/main/AGENTS.md)**: setup and usage rules for any agent (Codex, Cursor, Copilot, Gemini; Claude Code reads it via `CLAUDE.md`).
@@ -231,10 +252,14 @@ pip install iwork-studio # Python 3.12
231
252
  ```python
232
253
  from iwork_studio import numbers_structure, numbers_format, numbers_io, keynote_io, keynote_slides, exporter, backups
233
254
 
234
- from iwork_studio import keynote_deck, design
255
+ from iwork_studio import keynote_deck, design, review
235
256
 
236
257
  keynote_deck.build_deck("pitch.key", [{"title": "رسال", "body": "Programmable value"},
237
- {"title": "Why now", "body": ["Trust", "Access"]}], kit="midnight") # macOS + Keynote
258
+ {"title": "Why now", "body": ["Trust", "Access"]},
259
+ {"title": "Riyadh leads growth", "chart": {"type": "bar", "from": "sales.numbers"}}],
260
+ kit="midnight") # macOS + Keynote
261
+ review.review_deck("pitch.key")["findings"] # macOS + Keynote
262
+ design.extract_kit("brand.numbers", name="Resal", save=True)
238
263
  numbers_structure.import_csv("sales.csv", "sales.numbers")
239
264
  design.apply_to_numbers("sales.numbers", "banking")
240
265
  numbers_format.set_cell_style("sales.numbers", "A1:D1", bold=True, fill_color="#1A7F79", font_color="#FFFFFF")
@@ -269,6 +294,7 @@ backups.restore_backup("sales.numbers", backups.list_backups("sales.numbers")[0]
269
294
  18. **Numbers doesn't recalculate formulas when it opens a file changed without it**: a total keeps its old result. Edits made without the app say so, and `numbers_recalculate` has Numbers recompute every formula.
270
295
  19. **A rounding library used by numbers-parser wipes every warning filter in the process** on each save. It's wrapped so it stays quiet without touching anyone else's settings.
271
296
  20. **Don't keep the repo in iCloud Drive.** Sync creates "main 2" copies inside `.git`.
297
+ 21. **Keynote creates tables only one way**: `tell slide n to make new table` works, while `make new table at end of tables of slide n` and deleting a table fail with `-10000`. A failed table add is undone by restoring the backup.
272
298
 
273
299
  More, each with its status: [`jxa-traps.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/jxa-traps.md) (including traps borrowed from [reichenbach/iwork_mcp](https://github.com/reichenbach/iwork_mcp)).
274
300
 
@@ -285,10 +311,11 @@ MCP server · CLI scripts · skill → thin wrappers over t
285
311
 
286
312
  ```
287
313
  src/iwork_studio/ numbers_io · numbers_format · numbers_structure · keynote_io · keynote_slides · keynote_theme
288
- keynote_deck · design · preview · pages_io · app_ops · exporter · helpers · format_check
289
- render_verify · backups · apps · mcp_server
314
+ keynote_deck · keynote_table · design · review · preview · pages_io · app_ops · exporter
315
+ helpers · format_check · render_verify · pdf · backups · apps · mcp_server
290
316
  mcpb/ Claude Desktop extension manifest (scripts/build_mcpb.sh builds the .mcpb)
291
- skill-pack/ SKILL.md · CLI scripts · references (capabilities, traps, pins)
317
+ skill-pack/ SKILL.md · CLI scripts · references (capabilities, traps, pins); also the Claude Code plugin
318
+ .claude-plugin/ plugin marketplace (one plugin: skill-pack/)
292
319
  tests/ headless suite (CI) · `pytest -m aqua` = live suite for a Mac with iWork
293
320
  install.sh one-line setup for the Claude desktop app
294
321
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "iwork-studio"
7
- version = "2.3.0"
7
+ version = "2.4.0"
8
8
  description = "Create, edit, design and export Apple Numbers, Keynote and Pages files from any AI agent: verified, reversible, Arabic-safe. MCP server + Python library + agent skill."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,3 +1,3 @@
1
1
  """iWork Studio — verified read/write for Apple Numbers, Keynote and Pages."""
2
2
 
3
- __version__ = "2.3.0"
3
+ __version__ = "2.4.0"