fix(limrun): normalize variant iOS scalar attributes into snapshot text
Summary
snapshot failed with e?.trim is not a function on any Limrun iOS screen whose nodes report a numeric accessibility value — the system photo picker's segmented tabs report AXValue 1/0 as JSON numbers. iOS AXValue is a variant attribute, but the Limrun raw mapping forwarded it verbatim into RawSnapshotNode.value, which every producer publishes as text; consumers (react-native-overlay, snapshot-state) legitimately call ?.trim() trusting that contract.
The fix repairs the construction path, not the guards: packages/provider-limrun/src/snapshot.ts now normalizes label/value/identifier through one scalarText reader — the same normalization the Apple tree applies to its guest scalars — and widens IosTreeNode's text fields to the JSON union the provider actually sends. The issue's "Related (minor)" is the same seam: Selected in traits now publishes selected: true (omitted otherwise), the shape the Apple tree uses, so picked photos are visible and selected: selectors work. 3 files, no shared-consumer changes.
Closes #3634
Validation
Head 42ab24006. Same script mapping the picker's { AXLabel: 'Photos', AXValue: 1 } node and trimming value (base 8c01a3787 | head):
| base | head |
|---|---|
value: 1 typeof: number / trim threw: value?.trim is not a function | value: "1" typeof: string / trim: 1 |
pnpm check:affected --run: all runnable checks passed (128 files, 798 tests).vitest run --project unit-core: 14,288 passed.- New tests are revert-sensitive: without the fix
checkedis not derived from numericAXValueandSelectedyieldsselected: undefined. - Unresolved risk: no live Limrun session locally, so the provider integration lane on the PR head is the live evidence; the fixture reproduces the raw tree from the issue verbatim.