iwork-studio 2.3.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.
- iwork_studio-2.3.0/LICENSE +21 -0
- iwork_studio-2.3.0/PKG-INFO +348 -0
- iwork_studio-2.3.0/README.md +311 -0
- iwork_studio-2.3.0/THIRD_PARTY_NOTICES.md +43 -0
- iwork_studio-2.3.0/pyproject.toml +52 -0
- iwork_studio-2.3.0/setup.cfg +4 -0
- iwork_studio-2.3.0/src/iwork_studio/__init__.py +3 -0
- iwork_studio-2.3.0/src/iwork_studio/app_ops.py +1043 -0
- iwork_studio-2.3.0/src/iwork_studio/apps.py +80 -0
- iwork_studio-2.3.0/src/iwork_studio/backups.py +129 -0
- iwork_studio-2.3.0/src/iwork_studio/design.py +337 -0
- iwork_studio-2.3.0/src/iwork_studio/exporter.py +280 -0
- iwork_studio-2.3.0/src/iwork_studio/format_check.py +91 -0
- iwork_studio-2.3.0/src/iwork_studio/helpers.py +179 -0
- iwork_studio-2.3.0/src/iwork_studio/installer.py +150 -0
- iwork_studio-2.3.0/src/iwork_studio/keynote_applescript.py +226 -0
- iwork_studio-2.3.0/src/iwork_studio/keynote_deck.py +266 -0
- iwork_studio-2.3.0/src/iwork_studio/keynote_io.py +582 -0
- iwork_studio-2.3.0/src/iwork_studio/keynote_slides.py +430 -0
- iwork_studio-2.3.0/src/iwork_studio/keynote_theme.py +386 -0
- iwork_studio-2.3.0/src/iwork_studio/mcp_server.py +906 -0
- iwork_studio-2.3.0/src/iwork_studio/numbers_format.py +594 -0
- iwork_studio-2.3.0/src/iwork_studio/numbers_io.py +576 -0
- iwork_studio-2.3.0/src/iwork_studio/numbers_structure.py +368 -0
- iwork_studio-2.3.0/src/iwork_studio/pages_io.py +593 -0
- iwork_studio-2.3.0/src/iwork_studio/pdf.py +152 -0
- iwork_studio-2.3.0/src/iwork_studio/preview.py +140 -0
- iwork_studio-2.3.0/src/iwork_studio/render_verify.py +199 -0
- iwork_studio-2.3.0/src/iwork_studio.egg-info/PKG-INFO +348 -0
- iwork_studio-2.3.0/src/iwork_studio.egg-info/SOURCES.txt +52 -0
- iwork_studio-2.3.0/src/iwork_studio.egg-info/dependency_links.txt +1 -0
- iwork_studio-2.3.0/src/iwork_studio.egg-info/entry_points.txt +2 -0
- iwork_studio-2.3.0/src/iwork_studio.egg-info/requires.txt +11 -0
- iwork_studio-2.3.0/src/iwork_studio.egg-info/top_level.txt +1 -0
- iwork_studio-2.3.0/tests/test_app_ops.py +836 -0
- iwork_studio-2.3.0/tests/test_apps.py +83 -0
- iwork_studio-2.3.0/tests/test_backups.py +61 -0
- iwork_studio-2.3.0/tests/test_design.py +212 -0
- iwork_studio-2.3.0/tests/test_exporter.py +171 -0
- iwork_studio-2.3.0/tests/test_format_check.py +56 -0
- iwork_studio-2.3.0/tests/test_installer.py +95 -0
- iwork_studio-2.3.0/tests/test_keynote_deck.py +261 -0
- iwork_studio-2.3.0/tests/test_keynote_slides.py +334 -0
- iwork_studio-2.3.0/tests/test_keynote_theme.py +194 -0
- iwork_studio-2.3.0/tests/test_keynote_writer.py +335 -0
- iwork_studio-2.3.0/tests/test_mcp_server.py +233 -0
- iwork_studio-2.3.0/tests/test_numbers_format.py +131 -0
- iwork_studio-2.3.0/tests/test_numbers_structure.py +243 -0
- iwork_studio-2.3.0/tests/test_numbers_writer.py +251 -0
- iwork_studio-2.3.0/tests/test_packaging.py +62 -0
- iwork_studio-2.3.0/tests/test_pages_writer.py +423 -0
- iwork_studio-2.3.0/tests/test_preview.py +92 -0
- iwork_studio-2.3.0/tests/test_render_route.py +98 -0
- iwork_studio-2.3.0/tests/test_value_fidelity.py +57 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arkanji
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iwork-studio
|
|
3
|
+
Version: 2.3.0
|
|
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
|
+
Author: iWork Studio contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Arkanji/iwork-studio
|
|
8
|
+
Project-URL: Repository, https://github.com/Arkanji/iwork-studio
|
|
9
|
+
Project-URL: Changelog, https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/Arkanji/iwork-studio/issues
|
|
11
|
+
Keywords: iwork,numbers,keynote,pages,mcp,arabic,rtl,agent
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Office/Business :: Office Suites
|
|
20
|
+
Classifier: Natural Language :: Arabic
|
|
21
|
+
Classifier: Natural Language :: English
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
License-File: THIRD_PARTY_NOTICES.md
|
|
26
|
+
Requires-Dist: numbers-parser==4.19.0
|
|
27
|
+
Requires-Dist: keynote-parser==1.14.5.0
|
|
28
|
+
Requires-Dist: pdfminer.six==20260107
|
|
29
|
+
Requires-Dist: python-docx==1.2.0
|
|
30
|
+
Requires-Dist: mcp==2.2.0
|
|
31
|
+
Requires-Dist: openpyxl==3.1.5
|
|
32
|
+
Requires-Dist: python-pptx==1.0.2
|
|
33
|
+
Provides-Extra: test
|
|
34
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
35
|
+
Requires-Dist: reportlab==5.0.1; extra == "test"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
<div align="center">
|
|
39
|
+
|
|
40
|
+
<!-- mcp-name: io.github.Arkanji/iwork-studio -->
|
|
41
|
+
|
|
42
|
+
<img src="https://raw.githubusercontent.com/Arkanji/iwork-studio/main/assets/banner.svg" alt="iWork Studio — read and edit Apple Numbers, Keynote and Pages with Python" width="100%">
|
|
43
|
+
|
|
44
|
+
[](https://github.com/Arkanji/iwork-studio/blob/main/.github/workflows/ci.yml)
|
|
45
|
+
[](https://github.com/Arkanji/iwork-studio/blob/main/CHANGELOG.md)
|
|
46
|
+
[](https://github.com/Arkanji/iwork-studio/tree/main/LICENSE)
|
|
47
|
+
[](#what-it-can-do)
|
|
48
|
+
[](#all-58-tools)
|
|
49
|
+
[](#arabic--rtl)
|
|
50
|
+
[](#the-safety-model)
|
|
51
|
+
|
|
52
|
+
### Give your AI the keys to Apple iWork.
|
|
53
|
+
|
|
54
|
+
Create, edit, format, theme and export **Numbers**, **Keynote** and **Pages** files from Claude or any AI agent.<br>
|
|
55
|
+
Every write is backed up, checked and swapped in atomically, and any change can be undone with one call.
|
|
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)
|
|
58
|
+
|
|
59
|
+
<br>
|
|
60
|
+
|
|
61
|
+
<a href="https://arkanji.com/images/posts/iwork-studio-film-v3.mp4">
|
|
62
|
+
<img src="https://raw.githubusercontent.com/Arkanji/iwork-studio/main/assets/iwork-studio-film.webp" alt="iWork Studio in action: an AI agent edits a Numbers cell and keeps its formula, updates every Keynote slide without touching the formatting, and writes an Arabic letter in Pages" width="100%">
|
|
63
|
+
</a>
|
|
64
|
+
|
|
65
|
+
<sub>▶ <a href="https://arkanji.com/images/posts/iwork-studio-film-v3.mp4"><b>Watch the film with sound</b></a> (46s) · <a href="https://arkanji.com/posts/iwork-studio-launch/">Read the launch story</a></sub>
|
|
66
|
+
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Install
|
|
72
|
+
|
|
73
|
+
| Your app | Do this |
|
|
74
|
+
|---|---|
|
|
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
|
+
| **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` |
|
|
78
|
+
| **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
|
+
That's it. The installer sets up [`uv`](https://docs.astral.sh/uv/) if needed, and uv brings its own Python.
|
|
81
|
+
|
|
82
|
+
- **Fence it** (recommended): `… | sh -s -- --roots ~/Documents ~/Desktop` limits it to those folders. Other clients: set `IWORK_STUDIO_ROOTS` (`:`-separated).
|
|
83
|
+
- **First run:** macOS asks once whether Claude may control Keynote / Pages / Numbers. Click **OK**. (Missed it? System Settings → Privacy & Security → Automation.)
|
|
84
|
+
- **Check it:** ask *"what can iwork-studio do on this Mac?"*.
|
|
85
|
+
- **Remove:** `uvx --from git+https://github.com/Arkanji/iwork-studio iwork-studio-mcp uninstall`
|
|
86
|
+
|
|
87
|
+
> **AI agent setting this up for someone?** Pick the row for their app, run it, then call `iwork_capabilities`. Rules for using the tools are in [`AGENTS.md`](https://github.com/Arkanji/iwork-studio/blob/main/AGENTS.md).
|
|
88
|
+
|
|
89
|
+
## Just ask, in English or Arabic
|
|
90
|
+
|
|
91
|
+
> *"Build a 6-slide pitch deck on programmable gift cards in the midnight kit, with speaker notes, and export it to PowerPoint."*
|
|
92
|
+
>
|
|
93
|
+
> *"Make budget.numbers look professional with the banking kit — and show me a preview first."*
|
|
94
|
+
>
|
|
95
|
+
> *"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."*
|
|
96
|
+
>
|
|
97
|
+
> *"In pitch.key, switch to the Gradient theme, make the title on slide 1 white at 60 pt, add a dissolve between every slide, and put logo.png on the last slide."*
|
|
98
|
+
>
|
|
99
|
+
> *"Add a bar chart of revenue by quarter for 2025 and 2026 to slide 4."*
|
|
100
|
+
>
|
|
101
|
+
> *"Duplicate slide 3, move the copy to the front and add presenter notes: ملاحظات المتحدث"*
|
|
102
|
+
>
|
|
103
|
+
> *"Fill the Name and Date fields in offer-letter.pages, then export it as a password-protected PDF."*
|
|
104
|
+
>
|
|
105
|
+
> *"In the invoice.pages table, set the quantity in B3 to 12 and make D9 the total of D2:D8."*
|
|
106
|
+
>
|
|
107
|
+
> *"Find my Keynote decks from this week and export each one to PowerPoint."*
|
|
108
|
+
>
|
|
109
|
+
> *"Undo the last change to budget.numbers."*
|
|
110
|
+
|
|
111
|
+
## What it can do
|
|
112
|
+
|
|
113
|
+
| | **Numbers** | **Keynote** | **Pages** |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| **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 | — |
|
|
119
|
+
| **Export** | PDF · Excel · CSV | PDF · PowerPoint · images · movie | PDF · Word · EPUB · text · RTF |
|
|
120
|
+
| **Present** | | Start, stop, next, previous | |
|
|
121
|
+
|
|
122
|
+
⚡ = works anywhere, no app needed (pure Python). Everything else drives the real app on a Mac with a logged-in session, classic iWork or the Creator Studio apps.
|
|
123
|
+
|
|
124
|
+
**Every file type:** preview any change before it's made (`dry_run`), look up metadata, pull the preview thumbnail, find files with Spotlight, check that a word is visibly rendered, check the rendered font/size/colour, list backups and undo.
|
|
125
|
+
|
|
126
|
+
### What it won't do
|
|
127
|
+
|
|
128
|
+
On purpose, so it never breaks a file:
|
|
129
|
+
|
|
130
|
+
- **Files with charts** are refused by the tools that work without the app: their rewrite can silently break a chart's link to its data. The app-driven tools (Keynote slides, theming, transitions, images; Numbers formulas and sort) work on them and check every chart is still there.
|
|
131
|
+
- **Charts in Numbers and Pages** can't be created: Apple doesn't make them scriptable. Keynote charts can be added.
|
|
132
|
+
- **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
|
+
- **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.
|
|
135
|
+
|
|
136
|
+
## Designed, not just edited
|
|
137
|
+
|
|
138
|
+
Six **design kits** turn a plain deck or table into something you'd present: a font pair (Latin + Arabic, all bundled with macOS — nothing to install), a restrained palette checked for WCAG contrast, and a type scale.
|
|
139
|
+
|
|
140
|
+
| Kit | Feel |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `executive` | Calm and corporate: slate neutrals, one blue accent |
|
|
143
|
+
| `banking` | Trust and weight: deep navy, restrained gold |
|
|
144
|
+
| `classic` | Formal reports and boards: serif headings, navy and amber |
|
|
145
|
+
| `teal` | Fresh and confident: deep teal |
|
|
146
|
+
| `analytics` | Data-forward: strong blue, amber highlights |
|
|
147
|
+
| `midnight` | Dark stage: near-black slides, white titles, mint accent |
|
|
148
|
+
|
|
149
|
+
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
|
+
|
|
151
|
+
## The safety model
|
|
152
|
+
|
|
153
|
+
An iWork app will happily say "saved" about a file it just broke. Nothing here trusts "saved".
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
backup → change a scratch copy → re-open it and compare → atomic swap
|
|
157
|
+
↘ anything off: your file is untouched, the error says why
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- **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.
|
|
162
|
+
- **Atomic swap**: the file is replaced in one step, so a crash can't leave half a file.
|
|
163
|
+
- **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
|
+
- **Undo is one call**: `iwork_list_backups` → `iwork_restore_backup`. The restore backs up the current version first, so undo can be undone too.
|
|
165
|
+
- **Preview first**: every write takes `dry_run=true`. It runs the real change on a throwaway copy, with every check, and shows exactly what would change. Your file isn't touched.
|
|
166
|
+
- **New files never overwrite** an existing one.
|
|
167
|
+
- **Refuse, don't mangle.** The worst case is a clear "no", never a broken file.
|
|
168
|
+
|
|
169
|
+
## Arabic & RTL
|
|
170
|
+
|
|
171
|
+
- Arabic text round-trips exactly in all three apps, including presenter notes, Pages placeholders and Pages table cells.
|
|
172
|
+
- **Paragraph direction is checked in Pages.** A replace that flips a right-to-left paragraph to left-to-right is rolled back. Pages writes new paragraphs left-to-right, even Arabic ones, and scripting can't change that, so those are flagged: set the direction in Pages (Format › Text).
|
|
173
|
+
- 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
|
+
- When checking a rendered PDF, assert **one** Arabic word. PDF text layers reorder multi-word RTL text.
|
|
175
|
+
|
|
176
|
+
## All 58 tools
|
|
177
|
+
|
|
178
|
+
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
|
+
|
|
180
|
+
<details open>
|
|
181
|
+
<summary><b>Any file</b> (14)</summary>
|
|
182
|
+
|
|
183
|
+
| Tool | What it does |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `iwork_capabilities` | What this machine can do: apps, GUI session, which routes work |
|
|
186
|
+
| `iwork_read` | Any `.numbers` / `.key` / `.pages` → JSON |
|
|
187
|
+
| `iwork_find` | Find iWork files by kind and name (Spotlight on a Mac) |
|
|
188
|
+
| `iwork_metadata` · `iwork_thumbnail` | Template, app builds, format version, slide count · the stored preview image |
|
|
189
|
+
| `iwork_create` · `iwork_create_from_template` | New file from Apple's built-in templates · copy of your own file |
|
|
190
|
+
| `iwork_list_templates` | Built-in templates (Numbers, Pages) and themes (Keynote) |
|
|
191
|
+
| `iwork_list_design_kits` | Design kits: fonts, palettes, type scale |
|
|
192
|
+
| `iwork_export` | PDF, Excel, CSV, Word, EPUB, text, RTF, PowerPoint, slide images, movie; optional password |
|
|
193
|
+
| `iwork_verify_render` · `iwork_verify_format` | Rendered PDF shows this text · with this font, size, colour, page size |
|
|
194
|
+
| `iwork_list_backups` · `iwork_restore_backup` | Undo |
|
|
195
|
+
|
|
196
|
+
</details>
|
|
197
|
+
|
|
198
|
+
<details>
|
|
199
|
+
<summary><b>Numbers</b> (17)</summary>
|
|
200
|
+
|
|
201
|
+
| Tool | What it does |
|
|
202
|
+
|---|---|
|
|
203
|
+
| `numbers_create` · `numbers_import_csv` | New file from rows of data · from a CSV/TSV |
|
|
204
|
+
| `numbers_edit_cell` | Set one cell |
|
|
205
|
+
| `numbers_set_formula` | Put a formula in a cell; Numbers computes it |
|
|
206
|
+
| `numbers_recalculate` | Have Numbers recompute every formula after edits made without it |
|
|
207
|
+
| `numbers_insert` · `numbers_delete` | Rows or columns, anywhere |
|
|
208
|
+
| `numbers_add_table` | New table on a sheet, or on a new sheet |
|
|
209
|
+
| `numbers_sort` | Sort body rows by a column |
|
|
210
|
+
| `numbers_inspect_format` | Widths, heights, headers, merges, and every cell's style, number format and borders |
|
|
211
|
+
| `numbers_set_cell_style` | Font, size, bold/italic/underline/strike, colours, fill, alignment, wrap |
|
|
212
|
+
| `numbers_set_number_format` | Number, currency (any ISO code), %, scientific, fraction, date, text; decimals, separators, negatives |
|
|
213
|
+
| `numbers_set_borders` | All / outline / inner / one side; width, colour, style |
|
|
214
|
+
| `numbers_set_dimensions` · `numbers_set_headers` · `numbers_merge_cells` | Column widths and row heights · header rows/columns · merges |
|
|
215
|
+
|
|
216
|
+
</details>
|
|
217
|
+
|
|
218
|
+
<details>
|
|
219
|
+
<summary><b>Keynote</b> (20)</summary>
|
|
220
|
+
|
|
221
|
+
| Tool | What it does |
|
|
222
|
+
|---|---|
|
|
223
|
+
| `keynote_build_deck` | A new deck from an outline: titles, bullets, notes, images, transition, design kit |
|
|
224
|
+
| `keynote_set_slide_text` | Fill a slide's title and body |
|
|
225
|
+
| `keynote_apply_design` | Restyle every slide from a design kit |
|
|
226
|
+
| `keynote_replace_text` | Find/replace on every slide, formatting untouched |
|
|
227
|
+
| `keynote_list_slides` | Every slide's text, notes, hidden state and chart count |
|
|
228
|
+
| `keynote_add_slide` · `keynote_duplicate_slide` · `keynote_delete_slide` · `keynote_move_slide` · `keynote_skip_slide` | Slide operations |
|
|
229
|
+
| `keynote_set_presenter_notes` | Presenter notes |
|
|
230
|
+
| `keynote_list_themes` · `keynote_inspect_style` | Available themes · a deck's theme, layouts and text styling |
|
|
231
|
+
| `keynote_set_theme` · `keynote_set_slide_layout` · `keynote_format_text` | Theme · one slide's layout · one text item's font, size, colour |
|
|
232
|
+
| `keynote_set_transition` | Effect, duration, delay, auto-advance |
|
|
233
|
+
| `keynote_add_image` | Place an image on a slide |
|
|
234
|
+
| `keynote_add_chart` | Add a bar, line, area, pie or scatter chart from data |
|
|
235
|
+
| `keynote_slideshow` | Start, stop, next, previous |
|
|
236
|
+
|
|
237
|
+
</details>
|
|
238
|
+
|
|
239
|
+
<details>
|
|
240
|
+
<summary><b>Pages</b> (7)</summary>
|
|
241
|
+
|
|
242
|
+
| Tool | What it does |
|
|
243
|
+
|---|---|
|
|
244
|
+
| `pages_preflight` | Checks Pages can answer (run once first) |
|
|
245
|
+
| `pages_replace_all` · `pages_set_body` | Replace text everywhere · replace the whole body (resets its formatting) |
|
|
246
|
+
| `pages_list_placeholders` · `pages_fill_placeholders` | Template fields like Name and Date |
|
|
247
|
+
| `pages_read_tables` · `pages_set_table_cells` | Read every table · write text, numbers and formulas into an existing table |
|
|
248
|
+
|
|
249
|
+
</details>
|
|
250
|
+
|
|
251
|
+
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
|
+
|
|
253
|
+
## For AI agents
|
|
254
|
+
|
|
255
|
+
- **[`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`).
|
|
256
|
+
- **MCP instructions**: the server sends its rules on connect, so the model has them even without this repo.
|
|
257
|
+
- **Skill**: [`skill-pack/SKILL.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/SKILL.md), auto-discovered by Claude Code in this repo, or `bash skill-pack/install.sh` for other skill-based agents. It includes CLI scripts with JSON output for agents without MCP.
|
|
258
|
+
- **[`llms.txt`](https://github.com/Arkanji/iwork-studio/blob/main/llms.txt)**: a short machine-readable summary.
|
|
259
|
+
|
|
260
|
+
**The contract:** JSON in, JSON out. Errors are typed and say what to tell the user: `ChartRefusalError`, `DocumentOpenError`, `PagesOutOfScopeError`, `AquaSessionError` (no Mac GUI here) and so on. Don't retry a refused write with a trick.
|
|
261
|
+
|
|
262
|
+
## Python
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
pip install iwork-studio # Python 3.12
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from iwork_studio import numbers_structure, numbers_format, numbers_io, keynote_io, keynote_slides, exporter, backups
|
|
270
|
+
|
|
271
|
+
from iwork_studio import keynote_deck, design
|
|
272
|
+
|
|
273
|
+
keynote_deck.build_deck("pitch.key", [{"title": "رسال", "body": "Programmable value"},
|
|
274
|
+
{"title": "Why now", "body": ["Trust", "Access"]}], kit="midnight") # macOS + Keynote
|
|
275
|
+
numbers_structure.import_csv("sales.csv", "sales.numbers")
|
|
276
|
+
design.apply_to_numbers("sales.numbers", "banking")
|
|
277
|
+
numbers_format.set_cell_style("sales.numbers", "A1:D1", bold=True, fill_color="#1A7F79", font_color="#FFFFFF")
|
|
278
|
+
numbers_format.set_number_format("sales.numbers", "B2:B99", "currency", currency_code="SAR", decimal_places=2)
|
|
279
|
+
numbers_io.edit_cell("sales.numbers", "B2", 2500)
|
|
280
|
+
keynote_io.edit_text("pitch.key", "2025", "2026")
|
|
281
|
+
keynote_slides.set_presenter_notes("pitch.key", 1, "ملاحظات") # macOS + Keynote
|
|
282
|
+
exporter.export("pitch.key", "pptx") # macOS + Keynote
|
|
283
|
+
backups.restore_backup("sales.numbers", backups.list_backups("sales.numbers")[0]["name"])
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
<details>
|
|
287
|
+
<summary><b>Traps we mapped so your agent doesn't hit them</b></summary>
|
|
288
|
+
|
|
289
|
+
1. **`save in <path>` is denied by the iWork sandbox.** In-place `save` and `export` work. → [`sandbox-trap.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/sandbox-trap.md)
|
|
290
|
+
2. **Keynote's slide `title`/`body` properties throw `-1700`.** Use the text item's `object text`. → [`keynote-1700-defect.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/keynote-1700-defect.md)
|
|
291
|
+
3. **Chart files corrupt quietly** when the file-level libraries rewrite them, so those routes refuse them. When the app makes the edit it keeps its own charts linked, so app-driven routes allow them and count every chart before and after.
|
|
292
|
+
4. **Byte-equal saves don't exist** in iWork's format. The real bar is semantic: it reopens, and the full model matches.
|
|
293
|
+
5. **First-run permission and template-chooser dialogs** block every script call. A preflight turns the hang into one clear prompt. → [`tcc-preflight.md`](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/tcc-preflight.md)
|
|
294
|
+
6. **"Creator Studio" apps have different names.** A hardcoded `Application("Numbers")` drives the wrong app; names are resolved per call. → [`apps.py`](https://github.com/Arkanji/iwork-studio/blob/main/src/iwork_studio/apps.py)
|
|
295
|
+
7. **stdout is the MCP wire.** Import-time warnings from libraries would corrupt it, so they go to stderr.
|
|
296
|
+
8. **Keynote's JavaScript insert and move are broken**; AppleScript `make new slide` and `move slide … to before slide …` work.
|
|
297
|
+
9. **Keynote master slides can't be reached from JavaScript** (`-1700`); layouts go through AppleScript.
|
|
298
|
+
10. **numbers-parser doesn't save in-place style edits.** Styles are registered first, then applied.
|
|
299
|
+
11. **numbers-parser stored 12 as 12.000000000000002.** Decimals are now encoded exactly.
|
|
300
|
+
12. **numbers-parser doesn't update formula references when rows move**, so mid-table inserts in formula tables are refused.
|
|
301
|
+
13. **Keynote colours are 0–65535 per channel**, not 0–255 or 0–1.
|
|
302
|
+
14. **Pages page-layout documents have no body text** (`bodyText()` is null), and most letter and flyer templates are page layout. Placeholders are filled and checked across every text box instead.
|
|
303
|
+
15. **Pages tables are invisible to JavaScript** scripting but readable and writable from AppleScript; creating tables is broken in Pages 15, so only existing tables are offered.
|
|
304
|
+
16. **The Pages sandbox refuses AppleScript `open`** for files outside it; JavaScript `open` is allowed, so documents are opened that way and then found by their exact path.
|
|
305
|
+
17. **numbers-parser can break formulas on re-save** (an upstream report). Every no-app write compares every formula, so a broken one is caught and nothing changes.
|
|
306
|
+
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
|
+
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
|
+
20. **Don't keep the repo in iCloud Drive.** Sync creates "main 2" copies inside `.git`.
|
|
309
|
+
|
|
310
|
+
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
|
+
|
|
312
|
+
</details>
|
|
313
|
+
|
|
314
|
+
<details>
|
|
315
|
+
<summary><b>How it's built</b></summary>
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
pure Python file parsers (headless, deterministic) → .numbers everything, .key text
|
|
319
|
+
the real app via AppleScript / JXA → .key slides & theming, .pages text & tables, formulas, sort, export, render checks
|
|
320
|
+
MCP server · CLI scripts · skill → thin wrappers over the same library and the same safety model
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
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
|
|
327
|
+
mcpb/ Claude Desktop extension manifest (scripts/build_mcpb.sh builds the .mcpb)
|
|
328
|
+
skill-pack/ SKILL.md · CLI scripts · references (capabilities, traps, pins)
|
|
329
|
+
tests/ headless suite (CI) · `pytest -m aqua` = live suite for a Mac with iWork
|
|
330
|
+
install.sh one-line setup for the Claude desktop app
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
</details>
|
|
334
|
+
|
|
335
|
+
## Contributing
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
git clone https://github.com/Arkanji/iwork-studio.git && cd iwork-studio
|
|
339
|
+
uv run --extra test pytest -m "not aqua" # headless suite, what CI runs
|
|
340
|
+
uv run --extra test pytest -m aqua # live suite: a Mac with Numbers, Keynote and Pages
|
|
341
|
+
scripts/live.sh # the same, unattended: logs to ~/.iwork-studio/probes, quits the apps it opened
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
iWork changes between releases. If something breaks, check the [capabilities](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/capability-matrix.md) and [traps](https://github.com/Arkanji/iwork-studio/blob/main/skill-pack/references/jxa-traps.md), run the live suite, and pin what changed. New write routes must follow the safety model and come with tests that prove the rollback. Clone outside iCloud-synced folders.
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
[MIT](https://github.com/Arkanji/iwork-studio/tree/main/LICENSE), traps included. Take them.
|