Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ee68a6e
Add Apple Vision Pro support: wireless pairing + install over an RP t…
rebelancap Jul 15, 2026
f87d47c
Fix macOS Local Network discovery and first-attempt wireless pairing
rebelancap Jul 27, 2026
1f79f51
Detect default-named Vision Pros; explain unreachable-headset errors
rebelancap Jul 27, 2026
4e58fcc
Keep the friendly device name; explain Xcode pairing coexistence
rebelancap Jul 27, 2026
b9d9c82
Don't pair to a withdrawn manual-pairing port
rebelancap Jul 27, 2026
0798d89
Try every advertised address; keep the pairing when unreachable
rebelancap Jul 28, 2026
01b0b05
Fix headsets advertising a single address being dropped entirely
rebelancap Jul 28, 2026
eba82ee
Never lose a routable address; keep proven pairings; retry AFC uploads
rebelancap Jul 28, 2026
cf93ea0
Tell instant macOS connect refusals apart from unanswered headsets
rebelancap Jul 28, 2026
ffb8e8f
Fix the black window on connection errors; log the pairing timeline
rebelancap Jul 28, 2026
b8d6e84
Warn when this build is ad-hoc signed (macOS blocks its local traffic)
rebelancap Jul 28, 2026
fa58aaf
Probe the Local Network filter from our own socket
rebelancap Jul 29, 2026
fce7145
Install LiveContainer2 (the auto-return relay) alongside LiveContaine…
rebelancap Aug 8, 2026
7533abe
Re-vendor isideload at upstream's pinned 0.3.17 commit; bump to 2.3.4
rebelancap Sep 14, 2026
5d45e35
Vision Pro sideload: adapt to isideload 0.3.17's sign_app progress arg
rebelancap Sep 14, 2026
430f844
Add an ignored GSA sign-in probe to verify the 503 fix
rebelancap Sep 14, 2026
2720d4d
vendor/isideload: drop the dangling README symlink and its manifest key
rebelancap Sep 14, 2026
a60bec6
Add STATUS.md for the upstream sync round
rebelancap Sep 14, 2026
3db538b
STATUS: record open keychain prompt and pending headset verification
rebelancap Sep 14, 2026
86adbf1
STATUS: fork 2.3.4 sign-in and Vision Pro install verified
rebelancap Sep 14, 2026
1ee7b6a
Release prep 2.3.5: SideStore visionOS 0.7.0 URL, version bump, notes
rebelancap Sep 14, 2026
4988d4f
STATUS: published 2026-09-14 round; live claims cleared
rebelancap Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ dist-ssr
keys
*.mobileprovision

dockerfile
dockerfile
# Local release artifacts
/build/
113 changes: 113 additions & 0 deletions STATUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# iloader (rebelancap fork) — STATUS

Branch: `visionos-tunnel` · version **2.3.5** · last updated 2026-09-14

## Current state

`visionos-tunnel` is rebased onto upstream `origin/main` (nab138/iloader
`348eefd`, 2026-09-10) and carries all 13 substantive Vision Pro commits plus the
re-done vendoring. Apple's GSA 503 block on `com.apple.dt.Xcode` client-info is
fixed: `src-tauri/vendor/isideload` is now an exact copy of the commit upstream
pins (`nab138/isideload@f6a4d5dba717d72fc2af63eaba26b27ba44116be`, branch
`apple-codesign-quick`, 0.3.17, containing a19f5f0's hardcoded
`<com.apple.AuthKit/1 (com.apple.akd/1.0)>`), overridden through
`[patch."https://github.com/nab138/isideload"]`. The only isideload patch we
still carry locally is the LiveContainer main-bundle certificate injection
(`ALTCertificate.p12` + `ALTCertificateID` + `ALTCertificatePassword`) — the
developer-error-35 "device already registered" tolerance is now upstream
verbatim. `vendor/idevice` is untouched at 0.1.65 (upstream's lock still resolves
0.1.65) and still carries the `awaitingUserConsent` real-pairing-code patch;
Cargo resolves a single idevice. Signed release build and DMG produced, all 5
unit tests pass, frontend typechecks. A real GSA sign-in reaches Apple and gets a
parsed plist error, not the HTML 503.

## Last round (2026-09-14, 2.3.5 release prep)

- `SIDESTORE_VP_URL` in `src-tauri/src/sideload.rs` repointed to
`rebelancap/SideStore` release **`visionos-0.7.0`**; the doc comment now records
the akd sign-in fix and the adi.pb reset requirement. LiveContainer URLs on the
rolling `visionos` tag are unchanged.
- Version bumped 2.3.4 -> **2.3.5**. `bun run bump-patch` covers `package.json`,
`src-tauri/Cargo.toml` and `src-tauri/tauri.conf.json` but runs with `--no-lock`,
so `src-tauri/Cargo.lock`'s `iloader` entry was edited by hand — check it every
bump.
- Signed release build succeeded (`bun run tauri build --target aarch64-apple-darwin
--config src-tauri/ci.conf.json`); the bundle_dmg.sh hang did not recur. DMG
copied to `build/iloader-visionOS-aarch64.dmg` (9.4 MB); `build/` is git-ignored.
- Release notes for the rolling `visionos` release drafted at
`build/release-notes.md` (existing body plus a "What's new in 2.3.5" section).
- **BLOCKED: notarization.** `xcrun notarytool submit --keychain-profile iloader`
fails with `Error: No Keychain password item found for profile: iloader`, and no
`com.apple.gke.notary.tool` item is visible in the (unlocked, no-timeout) login
keychain. `spctl -a -t open -vv build/iloader-visionOS-aarch64.dmg` therefore
reports `rejected / source=Unnotarized Developer ID`. The DMG IS validly signed
with `Developer ID Application: Austin Archibald (57G8J46Z2T)`. Austin must
re-run `xcrun notarytool store-credentials iloader` (apple-id
austin@archibalds.tv, team 57G8J46Z2T, app-specific password) before the DMG can
be notarized, stapled and published. **Do not upload the DMG as-is.**
- Nothing pushed, nothing uploaded.

## Last round (2026-09-13, upstream sync)

- Committed the dirty Cargo.lock; safety copy at
`backup/visionos-tunnel-pre-sync-2026-09-13` (old tip `d285365`).
- Rebased by cherry-picking the 13 substantive commits onto `origin/main`,
dropping all 14 "Bump version to 2.2.x" commits. Only non-trivial conflict:
`src-tauri/Cargo.toml` in the base VP commit (took upstream's git isideload
dependency, kept our idevice 0.1.65 + `installation_proxy` feature, kept our
vendor patch blocks). Every other conflict was the `iloader` version line in
`src-tauri/Cargo.lock`.
- Re-vendored isideload 0.3.17 and re-applied the LiveContainer patch, adapted to
0.3.17's synchronous `isideload_vfs::fs` file API.
- One API drift fix in our code: `sign_app` gained a `progress_callback`
parameter (`src-tauri/src/sideload.rs`, pass `None`). Nothing else broke.
- Version 2.3.4 (one patch above upstream's 2.3.3; ours had been 2.2.21) in
`package.json`, `src-tauri/Cargo.toml`, `src-tauri/tauri.conf.json`.
- Built `iloader_2.3.4_aarch64.dmg` signed with the Developer ID identity
(not notarized — no release this round).
- Verified sign-in through a new `#[ignore]`d probe,
`src-tauri/tests/gsa_signin.rs`: anisette provisioning succeeded, "Login step 1
completed", then Apple's own `AuthWithMessage(-22406, "Enter the correct
password for this Apple Account.")` using a deliberate placeholder password.
Independently confirmed with curl that GSA `POST /grandslam/GsService2` returns
503 for the Xcode client-info string and does not for the akd one.

## Last round (addendum, 2026-09-13 evening)

Fork 2.3.4 signed in to GSA for real (`Successfully logged in to Apple ID`, `Successfully retrieved app token`, no 503) and sideloaded ~/dev/sidestore/build/SideStore-visionOS.ipa (0.7.0) onto the Vision Pro over the RP tunnel: error-35 tolerance fired, InstallComplete, pairing file placed via Manage Pairing File. Sonnet review of the re-applied patches: no bugs.

## Published (2026-09-14)

Published 2026-09-14: iloader 2.3.5 (notarized) on rebelancap/iloader release `visionos`; SideStore 0.7.0 on rebelancap/SideStore release `visionos-0.7.0` (iloader URL updated); LC combo on rebelancap/LiveContainer release `visionos`. Branch visionos-tunnel force-pushed (rebased); backup branch pushed. Verified on headset: sign-in, registration, app update, icon after reboot.

## Next steps

1. **Restore the notarytool credential**: `xcrun notarytool store-credentials
iloader` (Apple ID austin@archibalds.tv, team 57G8J46Z2T, app-specific
password). Then, from `~/dev/iloader`:
`xcrun notarytool submit build/iloader-visionOS-aarch64.dmg --keychain-profile
iloader --wait` → `xcrun stapler staple build/iloader-visionOS-aarch64.dmg` →
`spctl -a -t open -vv build/iloader-visionOS-aarch64.dmg` (expect
`source=Notarized Developer ID`). The DMG needs no rebuild.
2. Create the `rebelancap/SideStore` release **`visionos-0.7.0`** with
`~/dev/sidestore/build/SideStore-visionOS.ipa` — iloader 2.3.5 already points at
that URL, so it 404s until the release exists.
3. Update the rolling `rebelancap/iloader` release `visionos`: body from
`build/release-notes.md`, asset `iloader-visionOS-aarch64.dmg` (`--clobber`),
only once notarized and stapled.
4. Update the `rebelancap/LiveContainer` `visionos` release with
`~/dev/LiveContainer/build/*.ipa`; push the sidestore submodule branches
(SideSign fb1a307, minimuxer eb67fe9) to the rebelancap forks.
5. Push `visionos-tunnel`. Austin decides whether 2.3.5 gets a GitHub release.

## Open questions

- Does 2.3.4 get a GitHub release, or does the next OTA/dev build become
2.3.4.1? Default if unanswered: no release, nothing pushed; the branch just
sits here.
- Should the LiveContainer main-bundle cert injection be offered upstream as a
PR against `apple-codesign-quick`? Default: keep it vendored.

## Live claims

None. Session closed cleanly 2026-09-14: nothing booted, no agents running, tree clean.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "iloader",
"private": true,
"version": "2.3.3",
"version": "2.3.5",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
77 changes: 73 additions & 4 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 31 additions & 2 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "iloader"
version = "2.3.3"
version = "2.3.5"
description = "User-friendly sideloader"
authors = ["nab138"]
edition = "2024"
Expand All @@ -22,7 +22,7 @@ tauri = { version = "2", features = ["devtools"] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
idevice = { version = "0.1.57", features = ["usbmuxd", "house_arrest", "afc", "core_device_proxy", "remote_pairing", "tcp", "tunnel_tcp_stack", "xpc", "rsd", "pair"] }
idevice = { version = "0.1.65", features = ["usbmuxd", "house_arrest", "afc", "installation_proxy", "core_device_proxy", "remote_pairing", "tcp", "tunnel_tcp_stack", "xpc", "rsd", "pair"] }
isideload = { version = "0.3.17", features = ["fs-storage"], git = "https://github.com/nab138/isideload", package = "isideload", branch = "apple-codesign-quick" }
keyring = { version = "3.6.3", features = ["apple-native", "windows-native", "linux-native-sync-persistent"] }
tauri-plugin-store = "2"
Expand All @@ -44,5 +44,34 @@ rootcause = "0.12.1"
thiserror = "2.0.18"
strum = {version = "0.28.0", features = ["derive"] }

# Vision Pro discovery. On macOS we go through the system Bonjour daemon
# (dns_sd / mDNSResponder) — raw-multicast mDNS is silently dropped by macOS 15+
# Local Network privacy when the OS fails to attribute it (no prompt, no Settings
# entry). Elsewhere there is no such gatekeeper and mdns-sd works fine.
[target.'cfg(target_os = "macos")'.dependencies]
async-dnssd = "0.5.1"

[target.'cfg(not(target_os = "macos"))'.dependencies]
mdns-sd = "0.19"

[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-updater = "2"

# isideload is overridden with an in-repo copy (vendor/isideload) of exactly the
# commit upstream pins (nab138/isideload @ f6a4d5db, branch apple-codesign-quick,
# 0.3.17), carrying one Vision Pro patch: apply_special_app_behavior also writes
# ALTCertificate.p12 + ALTCertificateID + ALTCertificatePassword into the MAIN app
# bundle for LiveContainer and SideStore+LiveContainer, so LiveContainer can open
# the p12 without user interaction. Drop this once that lands upstream.
# (The "device already registered" / developer error 35 tolerance we used to carry
# here is now in upstream 0.3.17, so it is no longer a local patch.)
[patch."https://github.com/nab138/isideload"]
isideload = { path = "vendor/isideload" }

# Vision Pro first-time pairing: published idevice hardcodes PIN "000000" when the
# device answers `awaitingUserConsent` (a Trust-dialog assumption). A Vision Pro
# answers that whenever its code screen isn't up yet, so every first pairing attempt
# failed with "missing server proof in SRP response". The vendored copy waits for the
# pairing data and asks the callback for the real on-screen code instead.
[patch.crates-io]
idevice = { path = "vendor/idevice" }
17 changes: 17 additions & 0 deletions src-tauri/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- iloader browses mDNS for an Apple Vision Pro (which advertises these
services) to reach it over Wi-Fi. macOS requires declaring local-network
usage and the specific Bonjour service types, or it silently blocks the
multicast discovery. -->
<key>NSLocalNetworkUsageDescription</key>
<string>iloader finds your Apple Vision Pro on your local network to pair with it and install apps over Wi-Fi.</string>
<key>NSBonjourServices</key>
<array>
<string>_remotepairing._tcp</string>
<string>_remotepairing-manual-pairing._tcp</string>
</array>
</dict>
</plist>
Loading