How to Contribute to the vphone-cli Project: A Complete Developer Guide

To contribute to vphone-cli, fork the repository with submodules, configure the Swift 6.0 development environment using the provided automation scripts, and submit pull requests that include unit tests and follow the project's formatting standards.

vphone-cli is a Swift 6.0 command-line tool that boots a virtual iPhone on Apple Silicon by leveraging the private PV = 3 entitlements of Virtualization.framework. Understanding how to contribute to vphone-cli requires familiarity with its multi-layered architecture spanning CLI parsing, VM lifecycle management, and binary firmware patching.

System Requirements and Prerequisites

Contributing to vphone-cli demands specific hardware and software configurations. You must run macOS 15 or later on Apple Silicon to utilize the required Virtualization.framework APIs.

Install the host dependencies using Homebrew before proceeding:

brew install python@3.13 ldid-procursus keystone

The firmware patcher relies on Capstone for disassembly, Keystone for re-assembly, and pyimg4 for IM4P blob manipulation. These tools bundle automatically into a Python virtual environment via the provided setup scripts.

Setting Up the Development Environment

Begin by forking the repository and cloning it with submodules to ensure you capture all dependencies:

git clone --recurse-submodules https://github.com/<your-username>/vphone-cli.git
cd vphone-cli

Bootstrap the toolchain and build environment by executing the automation scripts located in scripts/:

./scripts/setup_tools.sh      # Installs sub-module toolchains and creates .venv

./scripts/build.sh            # Builds, signs, and bundles the .app

Verify your baseline is clean by running the comprehensive test suite:

make test                     # Swift unit tests via Package.swift

./scripts/run_firmware_tests.sh  # Python firmware-patch validation

Understanding the vphone-cli Architecture

The codebase organizes functionality into four distinct layers. Knowing these boundaries helps you locate where to implement new features when you contribute to vphone-cli.

Command-Line Interface Layer

The CLI layer parses arguments and dispatches sub-commands. Core files include main.swift, VPhoneCLI.swift, and VPhoneVMCLI.swift, alongside concrete implementations like VPhoneVMCreateCLI.swift and VPhoneFWCLI.swift.

Virtual Machine Core

This layer constructs the VZVirtualMachineConfiguration and manages hardware models. Key files are VPhoneVirtualMachine.swift, VPhoneHardwareModel.swift, and VPhoneWindowController.swift.

Guest-Side Integration

The host communicates with the in-VM daemon (vphoned) via a vsock JSON protocol. Files such as VPhoneControl.swift, VPhoneMenuController.swift, and VPhoneFileBrowserModel.swift handle UI menus, file browsing, and IPA installation.

Firmware Patcher

Located under sources/FirmwarePatcher/, this component performs binary-level transformations for firmware variants (less, regular, dev, jb, exp). The pipeline orchestrates through FirmwarePipeline.swift and specialized classes like KernelJBPatcherBase.swift.

Contribution Areas and Implementation Patterns

When planning your vphone-cli contribution, focus on these high-impact areas:

Adding New CLI Sub-commands

Create a new Swift file under sources/vphone-cli/ conforming to the ArgumentParser protocol. Reference VPhoneVMCreateCLI.swift for the established pattern.

Example implementation of a ping command:

// sources/vphone-cli/VPhonePingCLI.swift
import ArgumentParser

struct VPhonePingCLI: ParsableCommand {
    static var configuration = CommandConfiguration(
        commandName: "ping",
        abstract: "Send a ping to the running VM's guest daemon."
    )

    @Option(name: .shortAndLong, help: "Name of the VM to ping.")
    var vm: String

    func run() throws {
        let ctrl = try VPhoneControl(vmName: vm)   // Reference: VPhoneControl.swift
        let resp = try ctrl.send(command: "ping", payload: [:])
        print("Response:", resp)
    }
}

Register the command in VPhoneCLI.swift by adding it to the subcommands array.

Extending Menu Functionality

For UI enhancements, create a new VPhoneMenu* class and register it in VPhoneMenuController.swift:

// sources/vphone-cli/VPhoneMenuDiagnostics.swift
import Cocoa

final class VPhoneMenuDiagnostics: NSObject {
    @objc func showDiagnostics(_ sender: Any?) {
        VPhoneVirtualMachine.shared?.dumpInfo()
    }
}

Hook the menu item in VPhoneMenuController.swift:

func setupMenus() {
    let diagItem = NSMenuItem(title: "Diagnostics", action: #selector(VPhoneMenuDiagnostics.showDiagnostics), keyEquivalent: "")
    menu.addItem(diagItem)
}

Firmware Patching

To add new kernel patches, extend FirmwarePipeline.swift or create a new Kernel*Patcher class following the style in KernelJBPatcherBase.swift. Consult research/0_binary_patch_comparison.md for detailed variant specifications.

Documentation Improvements

Enhance README sections, add language-specific guides, or expand the research/ markdown files with technical deep-dives.

Code Style and Standards

The project enforces consistency through SwiftPM formatting (swift format). Adhere to these conventions:

  • Keep changes minimal and focused
  • Add // MARK: sections for new logic blocks
  • Prefer private access modifiers where possible
  • Follow the conventions documented in AGENTS.md

Testing Requirements

Every contribution must include comprehensive test coverage. For Swift code, use XCTest and place test files adjacent to implementations (e.g., VPhoneMenuRecordTests.swift alongside VPhoneMenuRecord.swift). For firmware modifications, provide pytest validation scripts.

Run the full test matrix locally before submission to ensure compatibility with the CI pipeline running on macOS 15.

Submitting Your Contribution

Push your feature branch to your fork and open a pull request against the main repository. Reference related issues in your PR description. The CI system will execute the complete test suite including Swift unit tests and Python firmware validation. All checks must pass before maintainers can merge your code.

Summary

  • Fork and clone with --recurse-submodules to capture all dependencies
  • Run setup scripts (setup_tools.sh and build.sh) to configure the Swift 6.0 environment
  • Understand the four layers: CLI interface, VM core, guest integration, and firmware patching
  • Follow patterns: Use ArgumentParser for commands, VPhoneMenuController for UI, and FirmwarePipeline for binary patches
  • Maintain quality: Apply swift format, add // MARK: labels, and include unit tests
  • Verify locally: Execute make test and firmware tests before submitting PRs

Frequently Asked Questions

What programming languages does vphone-cli use?

vphone-cli is primarily written in Swift 6.0 for the CLI and VM management components. The firmware patcher uses Python with Capstone and Keystone engines for binary transformation. You should be comfortable with both languages to contribute across all subsystems.

Do I need special entitlements to test vphone-cli locally?

Yes. Testing the full virtualization features requires macOS 15+ on Apple Silicon hardware and the private PV = 3 entitlements for Virtualization.framework. The build scripts handle code signing automatically, but you must run the software on compatible hardware to validate VM functionality.

Where should I add tests for new firmware patches?

Add Python tests in the tests/ directory corresponding to the firmware patcher components. For a new Kernel*Patcher class, create parallel test files that validate the binary transformations against known good firmware images. Run these via ./scripts/run_firmware_tests.sh.

Can I contribute documentation without coding?

Absolutely. The research/ directory contains markdown files detailing binary patch comparisons and technical architecture. Improving README sections, adding usage examples, or creating troubleshooting guides in the documentation are valuable contributions that do not require Swift or Python development.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →