2024-04-03 02:45:58 -04:00

5.1 KiB


source for https://sheetjs.com/tools/iwa-inspector

iwa-inspector is a tool for inspecting iWork archives.

https://oss.sheetjs.com/notes/iwa/ covers the high-level structure of files. This inspector performs the top-level extraction of messages and parses using extracted Protocol Buffer definitions.


The sections are separated by a light gray horizontal line and a light gray vertical line. Panels can be resized by click-dragging the line.

Selecting a File

The file input element in the top-left corner of the page is limited to the IWA file types: .numbers, .key, and .pages.

The site automatically fetches a sample file on load.

Message Table

The message table is shown just below the header bar. The column headers are:

name description
id Message ID
type Numeric Message Type
message Absolute Message Type
path Location of Message

The table can be sorted by clicking on the column headers.

Searching for Messages

The search text box in the top-right corner of the page is a plaintext search over the parsed messages. Searches will match field names, string values and UUID fields of message type .TSP.UUID.

Selecting a Message

When a row in the table is selected, the bottom-left panel will display the Protocol Buffers definition for the message and the bottom-right panel will display the parsed contents.

Message Structure

The bottom-right panel shows the following information:

  • "Message": parsed information following the message definition
  • "Metadata": parsed information from the message metadata
  • "Dependents": list of messages that list the current message as a dependency.

Clicking on a message name in the inspector will show the message definition in the left pane. A "Return" link returns to the base message definition.

Clicking on a .TSP.Reference ID will jump to the referenced message.

Exporting Data

Right-clicking a custom message type will show a context menu with options to copy the raw byte representation (array of numbers) or parsed object (JSON).



make dev starts the dev server.

make build generates the static site.

make init installs dependencies.

Protos and Messages

make deps requires a SIP-disabled Mac with Keynote + Numbers + Pages.

The last run was on 2024-04-03 against version 14.0 (7039.0.94)

Software License Agreements

Before refreshing, each app must be launched once and the software license agreements must be accepted.

In the 13.2 update, Keynote clearly states

By clicking Continue you agree to the terms of the Keynote Software License Agreement

Curiously, the Numbers "What's New in Numbers" popup does not have a similar disclaimer. It is suspected that clicking "Continue" in Numbers and Pages serves a similar purpose.

Disabling SIP

  1. Enter Recovery mode:

On Intel Macs, shut down and restart while holding down Command+R keys.

On Apple Silicon Macs, shut down and restart while holding down the Touch ID. It will display a message "Continue holding for startup options". Let go once the message changes to "Loading startup options"

Select "Options" in the boot window and click the "Continue" button.

  1. Open a terminal window (Utilities > Terminal) and run the following command:
csrutil disable

If there is no error, restart the machine.

Apple Silicon Extra Steps

If the command fails with a message like

csrutil: The OS environment does not allow changing security configuration options.
Ensure that the system was booted into Recovery OS via the standard user action.
  1. Run the following command:
csrutil clear
  1. Open the "Startup Security Utility" (in the Utilities menu)

  2. Click "Security Policy..." and select "Permissive Security". Click "OK".

  3. Reboot into recovery mode (explained in Step 1)

  4. Open a terminal window (Utilities > Terminal) and run:

csrutil disable

Remember to re-enable SIP after updating messages!

Developer Tools error

Note: Runs may fail with an error like

error: Uncaught (in promise) "Could not find map!"

Running the command a second time typically shows a popup:

Developer Tools Access needs to take control of another process for debugging to continue

It will ask for Touch ID or password. After authorization, the build should run.

Protocol Buffer Details

Note that the message field is absolute. For example, TSTArchives.proto specifies the .TST.TileStorage as follows:

package TST;

message TileStorage {
  message Tile {
    required uint32 tileid = 1;
    required .TSP.Reference tile = 2;
  repeated .TST.TileStorage.Tile tiles = 1;
  optional uint32 tile_size = 2;
  optional bool should_use_wide_rows = 3;

The protobuf extractor rewrites the message names using the absolute form:

message .TST.TileStorage {
  message Tile {
    required uint32 tileid = 1;
    required .TSP.Reference tile = 2;
  repeated .TST.TileStorage.Tile tiles = 1;
  optional uint32 tile_size = 2;
  optional bool should_use_wide_rows = 3;