Commit Graph

2 Commits

Author SHA1 Message Date
Conor Luddy 5dd6a84593 fix(xcode27): keep xcrun working under the shim, auto-retire stale companions
Two follow-ups to #100, both found while investigating #101.

1. The shim's DEVELOPER_DIR broke every xcrun call in the same process.
   `common/__init__` sets DEVELOPER_DIR process-wide, and xcrun walks up from
   it looking for an enclosing .app bundle - a shim root named
   `xcode27-idb-shim` has none, so xcrun refused it outright:

     xcrun: error: unable to find Xcode installation from active developer
     path ".../xcode27-idb-shim/Contents/Developer"

   That broke all 22 scripts that shell out to `xcrun simctl` (screenshots,
   boot, io) on any Xcode 27 machine. Renaming the shim root to
   `Xcode27Shim.app` satisfies xcrun; idb is indifferent to the name. The
   pre-.app root is removed on next run.

2. A companion started before the shim stays broken for its whole lifetime -
   it inherits DEVELOPER_DIR once, at launch, and `idb connect` reuses the
   live process rather than replacing it. Scripts now retire any companion
   whose DEVELOPER_DIR is not the shim's.

   Killing the process alone is not enough: idb's registry at /tmp/idb/state
   still names the dead pid and its socket, so the next call dials a dead
   socket ("Connection refused") instead of spawning a replacement. Retired
   companions are evicted from the registry and their sockets unlinked, which
   removes the manual `pkill -f idb_companion` + `rm -f *.sock` dance from
   the #101 repro.

Verified on Xcode 27 / iOS 27.0 / iPhone 17 Pro: shim rebuilds from scratch,
xcrun and idb both work through it, a deliberately stale companion is retired
and recovered from transparently, and navigator.py taps land on screen.

Refs #100, #101
2026-09-12 07:49:07 +01:00
Conor 4207f82fc2 fix: shim idb-companion's SimulatorKit path for Xcode 27 (#100)
* fix: shim idb-companion's SimulatorKit path for Xcode 27

Xcode 27 moved SimulatorKit.framework from
Contents/Developer/Library/PrivateFrameworks/ to Contents/SharedFrameworks/.
idb-companion <= 1.1.8 still hardcodes the old path, so every `idb ui *`
call (navigator.py --tap, gesture.py, keyboard.py) failed outright with
"SimulatorKit is required for HID interactions" — the accessibility tree
still worked, but nothing could tap, swipe, or type.

common/xcode_compat.py builds a persistent DEVELOPER_DIR shim under
~/.ios-simulator-skill/ (symlinks back into the real Xcode.app, plus one
extra symlink exposing SimulatorKit at the legacy path) and points
DEVELOPER_DIR at it for the current process, so every idb subprocess
inherits the fix. common/__init__.py calls it at import time, so every
script that does `from common import ...` gets it for free with zero
call-site changes.

Backward compatible by construction: the legacy-path existence check
short-circuits on any Xcode where idb-companion already works, so this
is a no-op there. Opt out entirely with IOS_SIM_SKIP_XCODE27_SHIM=1.

* style: apply black formatting
2026-09-11 10:55:51 +01:00