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
* 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