Files
Ignacy Łątka dadd7037dd post-review fix: refuse same-frame collapse on conflicting label/value, pin AX→native fallback
Two findings from the verification pass:

1. Same-frame single-child collapse was silently dropping the wrapper's
   label when the child had its own. e.g.
     AXGroup label="Calendar widget" → AXButton label="Open"
   was folding to just `AXButton label="Open"`, losing the widget context.

   Now refuse the collapse when wrapper and child carry differing
   non-empty labels OR values. Identifier conflicts still collapse
   (child wins) — `id/content → id/launcher → id/drag_layer` chains
   in the Android launcher are platform-internal noise an agent never
   targets, so trimming them is fine.

2. compressDescribeTree on iOS now means an AX response containing
   only labelless trait-less elements adapts to a tree of pure
   AXGroup wrappers, all of which compress away, triggering the
   native-devtools fallback. Pin that behavior with a regression
   test in describe-tool.test.ts so future readers know it's
   intentional rather than an accident of the empty-children check.

Plus three small describe-compress tests (input-mutation safety,
empty-children root, fully no-op tree) covering invariants the
existing suite implied but did not assert.

Tests: 627 pass (was 620); +7 new.
2026-05-04 22:34:20 +02:00
..
2026-05-04 21:45:19 +02:00
2026-05-04 15:41:18 +02:00
2026-05-04 21:57:44 +02:00