[PR #1477] [MERGED] perf(apple): state each NIB object's class, label, and ID once #2915

Closed
opened 2026-10-17 21:11:47 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1477
Author: @kaoru0822-kitauji
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: perf/interface-builder-attribute-copies


📝 Commits (1)

  • f66374d perf(apple): state each NIB object's class, label, and ID once

📊 Changes

2 files changed (+40 additions, -1 deletions)

View changed files

📝 src/domain/apple/interfaceBuilderGraph.test.ts (+29 -0)
📝 src/domain/apple/interfaceBuilderKeyedArchive.ts (+11 -1)

📄 Description

Summary

decode_interface_builder decodes NIBArchive documents by turning each object into an ibtool-style record { customClass, label, objectID, nibValues }, so the shared ibtool dictionary parser can read it. REA does not run ibtool; this projection is the only producer of those dictionaries. The parser surfaces the values as the object's class_name, name and id. The graph node then also kept the synthesized copies in attributes, so each NIB object carried:

  • customClass and class_name with the same value,
  • label and the node's name with the same value,
  • objectID and interface_builder_object_id with the same value.

The parser now leaves out an attribute key when the matching canonical field already carries exactly that value. A key whose authored value differs (for example an objectID that is not the record key, or a class used when customClass is absent) is kept as before. nibValues and every other decoded field are unchanged.

Nothing in src reads attributes.customClass, attributes.label or attributes.objectID. The boundary tests look objects up by attributes.interface_builder_object_id, which is kept.

Measured effect

rea decode-interface-builder <app> --format json:

app main this branch
Transmission.app (NIBArchive) 6,445,757 6,143,942 (−4.7%)
XLD.app (keyed-archive NIBs only) 6,615,851 6,615,851 (byte-identical)

Verification

  • A new unit test in src/domain/apple/interfaceBuilderGraph.test.ts covers both cases: copies of the canonical values are dropped, and differing authored values are kept.
  • npx vitest run src/domain/apple src/artifacts/apple passes (160 tests).
  • npm run test:focused on tests/boundary/filesystem/{interfaceBuilderBundle,keyedArchiveSelection,appleXmlDeclarations}.test.ts and tests/boundary/mcp/enhancedTools.01-… passes, except the cases that need xcrun ibtool. This machine has only the Command Line Tools, so those also fail on main here. The macOS CI job runs them.
  • npm run check:fast and npm run docs:check pass.
  • I ran the CLI by hand against two real app bundles to get the numbers above.
  • No real Hopper or Ghidra verification was needed.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1477 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `perf/interface-builder-attribute-copies` --- ### 📝 Commits (1) - [`f66374d`](https://github.com/morluto/rea/commit/f66374da48e90aef1dd7095499b176e6a85e85ef) perf(apple): state each NIB object's class, label, and ID once ### 📊 Changes **2 files changed** (+40 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/apple/interfaceBuilderGraph.test.ts` (+29 -0) 📝 `src/domain/apple/interfaceBuilderKeyedArchive.ts` (+11 -1) </details> ### 📄 Description ## Summary `decode_interface_builder` decodes NIBArchive documents by turning each object into an ibtool-style record `{ customClass, label, objectID, nibValues }`, so the shared ibtool dictionary parser can read it. REA does not run ibtool; this projection is the only producer of those dictionaries. The parser surfaces the values as the object's `class_name`, `name` and `id`. The graph node then also kept the synthesized copies in `attributes`, so each NIB object carried: - `customClass` and `class_name` with the same value, - `label` and the node's `name` with the same value, - `objectID` and `interface_builder_object_id` with the same value. The parser now leaves out an attribute key when the matching canonical field already carries exactly that value. A key whose authored value differs (for example an `objectID` that is not the record key, or a `class` used when `customClass` is absent) is kept as before. `nibValues` and every other decoded field are unchanged. Nothing in `src` reads `attributes.customClass`, `attributes.label` or `attributes.objectID`. The boundary tests look objects up by `attributes.interface_builder_object_id`, which is kept. ## Measured effect `rea decode-interface-builder <app> --format json`: | app | main | this branch | |---|---|---| | Transmission.app (NIBArchive) | 6,445,757 | 6,143,942 (−4.7%) | | XLD.app (keyed-archive NIBs only) | 6,615,851 | 6,615,851 (byte-identical) | ## Verification - A new unit test in `src/domain/apple/interfaceBuilderGraph.test.ts` covers both cases: copies of the canonical values are dropped, and differing authored values are kept. - `npx vitest run src/domain/apple src/artifacts/apple` passes (160 tests). - `npm run test:focused` on `tests/boundary/filesystem/{interfaceBuilderBundle,keyedArchiveSelection,appleXmlDeclarations}.test.ts` and `tests/boundary/mcp/enhancedTools.01-…` passes, except the cases that need `xcrun ibtool`. This machine has only the Command Line Tools, so those also fail on `main` here. The macOS CI job runs them. - `npm run check:fast` and `npm run docs:check` pass. - I ran the CLI by hand against two real app bundles to get the numbers above. - No real Hopper or Ghidra verification was needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:11:47 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2915
No description provided.