Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
python -m ios_developer_toolkit.local_ddi --help
python -m ios_developer_toolkit.ipa_inspector --help
python -m ios_developer_toolkit --toolkit-internal-pymobiledevice3 version
- name: Verify guided command catalog
run: python scripts/verify_command_catalog.py
- name: Validate GUI actions
env:
QT_QPA_PLATFORM: offscreen
Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/frozen-macos-smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Frozen macOS smoke

on:
pull_request:
paths:
- ".github/workflows/frozen-macos-smoke.yml"
- "ios_developer_toolkit/**"
- "macos/**"
- "packaging/**"
- "requirements/**"
- "scripts/build_macos_release.sh"
- "scripts/collect_third_party_licenses.py"
- "scripts/verify_release_metadata.py"
- "scripts/verify_macos_bundle.py"
- "scripts/verify_command_catalog.py"
- "pyproject.toml"
- "tests/**"
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: frozen-macos-smoke-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-verify:
name: Build and verify ${{ matrix.architecture }} bundle
strategy:
fail-fast: false
matrix:
include:
- runner: macos-15
architecture: arm64
python_architecture: arm64
- runner: macos-15-intel
architecture: x86_64
python_architecture: x64
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.13"
architecture: ${{ matrix.python_architecture }}
cache: pip
- uses: actions/cache@v6
with:
path: ${{ runner.temp }}/nuitka-cache
key: nuitka-${{ runner.os }}-${{ matrix.architecture }}-${{ hashFiles('pyproject.toml', 'requirements/**', 'packaging/**') }}
restore-keys: |
nuitka-${{ runner.os }}-${{ matrix.architecture }}-
- name: Build the frozen application and run embedded checks
env:
MACOSX_DEPLOYMENT_TARGET: "13.0"
NUITKA_CACHE_DIR: ${{ runner.temp }}/nuitka-cache
run: |
release_version="$(python3 -c 'from ios_developer_toolkit import APP_VERSION; print(APP_VERSION)')"
./scripts/build_macos_release.sh "$release_version" "$RUNNER_TEMP/release-smoke" python3
- name: Confirm smoke artifacts exist
run: |
find "$RUNNER_TEMP/release-smoke" -maxdepth 1 -type f -name '*.zip' -size +0c -print -quit | grep -q .
find "$RUNNER_TEMP/release-smoke" -maxdepth 1 -type f -name '*.cdx.json' -size +0c -print -quit | grep -q .
10 changes: 10 additions & 0 deletions .github/workflows/release-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,24 @@ jobs:
architecture: x86_64
python_architecture: x64
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.13"
architecture: ${{ matrix.python_architecture }}
cache: pip
- uses: actions/cache@v6
with:
path: ${{ runner.temp }}/nuitka-cache
key: nuitka-${{ runner.os }}-${{ matrix.architecture }}-${{ hashFiles('pyproject.toml', 'requirements/**', 'packaging/**') }}
restore-keys: |
nuitka-${{ runner.os }}-${{ matrix.architecture }}-
- name: Build and verify native application
env:
MACOSX_DEPLOYMENT_TARGET: "13.0"
NUITKA_CACHE_DIR: ${{ runner.temp }}/nuitka-cache
run: ./scripts/build_macos_release.sh "${GITHUB_REF_NAME#v}" release-assets python3
- uses: actions/upload-artifact@v7
with:
Expand Down
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ authors:
repository-code: "https://github.com/hideouts-io/iOS-Developer-Toolkit"
url: "https://github.com/hideouts-io/iOS-Developer-Toolkit/releases/latest"
license: MIT
version: 0.3.1
date-released: "2026-08-30"
version: 0.3.4
date-released: "2026-09-21"
abstract: "A safety-focused macOS workbench for Developer Disk Images, pymobiledevice3 and DVT diagnostics, iOS logs, packet capture, location simulation, app inspection, backups, and evidence preservation."
keywords:
- iOS development
Expand Down
43 changes: 27 additions & 16 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion SOURCE_AVAILABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ The prebuilt application is accompanied by an architecture-specific CycloneDX SB

## Bundled third-party source

The release-critical upstream source locations and license information are recorded in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). In particular, the packaged `pymobiledevice3` release is available at its [matching upstream tag](https://github.com/doronz88/pymobiledevice3/tree/v10.11.0), including its GPL-3.0-or-later license. The project’s public tagged source, package inventory, and embedded notices are intended to make the source and license boundary inspectable before redistribution.
The release-critical upstream source locations and license information are recorded in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). In particular, the packaged `pymobiledevice3` release is available at its [matching upstream tag](https://github.com/doronz88/pymobiledevice3/tree/v11.15.1), including its GPL-3.0-or-later license. The project’s public tagged source, package inventory, and embedded notices are intended to make the source and license boundary inspectable before redistribution.

PySide6/Qt, Nuitka, CPython, and every other dependency remain subject to their own terms. Consult the generated `Contents/Resources/Licenses/` inventory in the application and the matching SBOM for the exact package set. This document is an availability and attribution statement, not legal advice.
6 changes: 3 additions & 3 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ The prebuilt macOS application contains or is built from the following release-c

| Component | Pinned release | Role | Declared license | Source and license information |
|---|---:|---|---|---|
| [pymobiledevice3](https://github.com/doronz88/pymobiledevice3) | 10.11.0 | Bundled Apple-device protocol implementation and command surface | GPL-3.0-or-later | [Source for 10.11.0](https://github.com/doronz88/pymobiledevice3/tree/v10.11.0) and [license](https://github.com/doronz88/pymobiledevice3/blob/v10.11.0/LICENSE) |
| [PySide6](https://doc.qt.io/qtforpython-6/) and Shiboken6 | 6.11.2 | Bundled Qt for Python GUI and bindings | LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only, as declared by the installed wheels | [Qt for Python source](https://code.qt.io/cgit/pyside/pyside-setup.git/tag/?h=v6.11.2) and [Qt licensing](https://www.qt.io/licensing/open-source-lgpl-obligations) |
| [Nuitka](https://github.com/Nuitka/Nuitka) | 4.1.1 | Release compiler; generated applications contain separately licensed Nuitka runtime material | Compiler: GNU AGPL v3; runtime terms are supplied by Nuitka in `LICENSE-RUNTIME.txt` | [Source for 4.1.1](https://github.com/Nuitka/Nuitka/tree/4.1.1) |
| [pymobiledevice3](https://github.com/doronz88/pymobiledevice3) | 11.15.1 | Bundled Apple-device protocol implementation and command surface | GPL-3.0-or-later | [Source for 11.15.1](https://github.com/doronz88/pymobiledevice3/tree/v11.15.1) and [license](https://github.com/doronz88/pymobiledevice3/blob/v11.15.1/LICENSE) |
| [PySide6 Essentials](https://doc.qt.io/qtforpython-6/) and Shiboken6 | 6.9.3 | Bundled Qt Core, GUI, Widgets, deployment tooling, and Python bindings | LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only, as declared by the installed wheels | [Qt for Python source](https://code.qt.io/cgit/pyside/pyside-setup.git/tag/?h=v6.9.3) and [Qt licensing](https://www.qt.io/licensing/open-source-lgpl-obligations) |
| [Nuitka](https://github.com/Nuitka/Nuitka) | 4.2.1 | Release compiler; generated applications contain separately licensed Nuitka runtime material | Compiler: GNU AGPL v3; runtime terms are supplied by Nuitka in `LICENSE-RUNTIME.txt` | [Source for 4.2.1](https://github.com/Nuitka/Nuitka/tree/4.2.1) |
| [CPython](https://github.com/python/cpython) | GitHub runner's Python 3.13 patch release | Bundled Python runtime | Python Software Foundation License Version 2 | [Source and license](https://github.com/python/cpython/blob/3.13/LICENSE) |

Each architecture-specific release also contains:
Expand Down
70 changes: 70 additions & 0 deletions docs/PHYSICAL_DEVICE_TEST_PROTOCOL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Physical-device test protocol

Use this protocol only with an iPhone or iPad that you own or are authorized to test. Keep raw UDIDs, device names, logs, captures, backups, screenshots, coordinates, and case evidence out of issues, pull requests, and compatibility reports.

## Required test context

Record these non-secret facts locally before testing:

* toolkit commit and application version;
* source or packaged build and native architecture;
* macOS, Xcode, Python, and `pymobiledevice3` versions;
* iPhone or iPad model, iOS version, build, and USB or network connection;
* whether Developer Mode, a DDI, and an RSD tunnel are expected for the tested workflow.

Do not record the raw UDID in a shared report. The application's Real-Device Compatibility view stores a one-way device fingerprint for local comparisons.

## Stage 1 — connection readiness

1. Connect the unlocked device directly with a known data-capable cable. Avoid hubs for the first test.
2. Accept **Allow accessory to connect** on macOS when shown.
3. Tap **Trust** on the device and enter its passcode when shown.
4. Confirm that Finder or Xcode lists the device.
5. Run `pymobiledevice3 usbmux list` in the project environment. Expect one JSON device record.
6. Run `xcrun devicectl list devices`. Expect the same device to be `available (paired)`.
7. Open the toolkit. Expect the physical device in the picker, an **Authorized device connected** banner, and a **devices-available** Connection diagnostic.
8. Disconnect and reconnect once. Expect the picker and banner to recover without restarting `usbmuxd`, deleting pairing records, or requiring `sudo`.

Failure boundaries:

* absent from the macOS USB tree: cable, port, lock state, or accessory-authorization problem;
* present in USB but absent from usbmux: pairing or Apple Mobile Device service problem;
* present in usbmux but absent from CoreDevice: Xcode/CoreDevice state problem;
* present in both CLIs but absent from the toolkit: application discovery regression; create a sanitized support bundle.

## Stage 2 — read-only application checks

1. Run the full **Capability Matrix** and save a local compatibility observation.
2. Verify that each row distinguishes ready, needs attention, unavailable, blocked, not tested, and not applicable.
3. Run finite read-only Command Center presets for device information, battery, date, mounted images, and installed applications.
4. Open Unified Log, syslog, and DVT OSLog separately. Confirm that each stream starts, receives data, pauses, filters, stops, and offers an explicit raw-save decision.
5. Run app inventory and local IPA inspection without installing or uninstalling an app.
6. Create a sanitized support bundle. Inspect the ZIP and confirm that it contains no raw device identity, command output, capture, log, credential, or user-entered value.

Expected result: every command either completes with bounded output or remains visibly identified as a stream with an enabled Stop control. No read-only check changes device state.

## Stage 3 — developer-service checks

Perform this stage only when Developer Mode is intentionally enabled.

1. Enable Developer Mode through iOS Settings and complete the required restart.
2. Mount the appropriate personalized DDI or use the Xcode candidate DDI when the selected workflow explicitly calls for it.
3. Re-run only the Developer Mode, DDI, RSD, DVT, and CoreDevice capability rows.
4. Verify DVT directory listing, application listing, and one bounded developer-service snapshot.
5. Start and stop DVT network activity. Confirm that the UI treats it as a stream rather than a finite snapshot.

Expected result: readiness changes are attributed to the correct layer. A DDI success does not imply that an RSD tunnel or every DVT service is available.

## Stage 4 — opt-in state-changing checks

These checks are not required for merge readiness. Run only when their device effect is acceptable and the displayed target is correct.

* **Location Lab:** set a harmless test coordinate, verify the visible simulated state, then use Clear and confirm that no simulation process remains.
* **IPA sideload:** inspect an eligible development-signed IPA first, install it with the device-bound acknowledgement, verify inventory, then uninstall only if planned.
* **Encrypted backup:** use protected local storage, verify the existing encryption state, understand that enabling backup encryption persists on the device, and confirm the resulting backup independently.
* **PCAP/RVI:** capture a short authorized trace, stop cleanly, open the file in an independent packet analyzer, and document encrypted-payload limitations.
* **Evidence case:** create a disposable case, collect one bounded artifact, finalize it, and independently verify its SHA-256 manifest.

## Completion record

Mark each stage as **passed**, **failed**, **not applicable**, or **not tested**. For failures, record the exact layer, command or button, exit status, sanitized error, and whether the failure reproduces in both the source and packaged app. Never convert **not tested** into a compatibility claim.
Loading
Loading