Compare commits

...

12 commits
3.1.12 ... main

Author SHA1 Message Date
CelloSerenity
1256c52803
Fix DeepWiki embed
Some checks are pending
Build Debug IPA / Build IPA (push) Waiting to run
Build Debug IPA / Update website source (push) Blocked by required conditions
2026-10-15 11:41:27 -04:00
CelloSerenity
3422fc4725
3.1.15 2026-10-15 10:30:45 -04:00
CelloSerenity
734361bb9d fix: handle legacy and cryptex DDI service discovery 2026-10-14 23:26:00 -04:00
CelloSerenity
cd5e609387
Update README.md 2026-10-12 06:56:38 -06:00
CelloSerenity
e4665d74b5
Update SettingsView.swift 2026-10-12 06:56:17 -06:00
CelloSerenity
300ebff50b
3.1.14 2026-10-11 21:13:08 -06:00
CelloSerenity
775fba15f3
Update AutoScriptAssignments.swift 2026-10-10 17:53:12 -06:00
CelloSerenity
871f1461d9
Update README.md 2026-10-04 14:09:38 -06:00
CelloSerenity
4bdfc92aa7
3.1.13 2026-09-28 08:29:15 -06:00
CelloSerenity
4b3c8d6e88
Rename 'MeloCafe' to 'MeloCafé' 2026-09-28 08:24:29 -06:00
c03abcaa44
Update AutoScriptAssignments.swift 2026-09-28 07:32:03 -04:00
CelloSerenity
d4306e724b
3.1.12 ReadMe 2026-09-27 15:26:08 -06:00
7 changed files with 73 additions and 76 deletions

View file

@ -7,24 +7,17 @@
<p><i>An on-device debugger/JIT enabler for iOS versions 17.4+ powered by <a href="https://github.com/jkcoxson/idevice">idevice</a>.</i></p>
</div>
<h6 align="center">
<a href="https://discord.gg/ZnNcrRT3M8">
<img src="https://img.shields.io/badge/Discord-join%20us-7289DA?logo=discord&logoColor=white&style=for-the-badge&labelColor=23272A" />
</a>
<a href="https://github.com/StikDebug/StikDebug/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/StikDebug/StikDebug?label=License&color=5865F2&style=for-the-badge&labelColor=23272A" />
</a>
<a href="https://github.com/StikDebug/StikDebug/stargazers">
<img src="https://img.shields.io/github/stars/StikDebug/StikDebug?label=Stars&color=FEE75C&style=for-the-badge&labelColor=23272A" />
</a>
<a href="https://github.com/StikDebug/StikDebug/releases">
<img src="https://img.shields.io/github/v/release/StikDebug/StikDebug?label=Latest&color=00BFFF&style=for-the-badge&labelColor=23272A" />
</a>
<br />
</h6>
<h3 align="center">
<a href="https://discord.gg/ZnNcrRT3M8"><img src="https://img.shields.io/badge/Discord-join%20us-7289DA?logo=discord&logoColor=white&style=for-the-badge&labelColor=23272A" /></a>&nbsp;
<a href="https://github.com/StikDebug/StikDebug/blob/main/LICENSE"><img src="https://img.shields.io/github/license/StikDebug/StikDebug?label=License&color=5865F2&style=for-the-badge&labelColor=23272A" /></a>&nbsp;
<a href="https://github.com/StikDebug/StikDebug"><img src="https://img.shields.io/github/stars/StikDebug/StikDebug?label=Stars&color=FEE75C&style=for-the-badge&labelColor=23272A" /></a>&nbsp;
<a href="https://github.com/StikDebug/StikDebug/releases"><img src="https://img.shields.io/github/v/release/StikDebug/StikDebug?label=Latest&color=00BFFF&style=for-the-badge&labelColor=23272A" /></a>&nbsp;
<a href="https://deepwiki.com/StikDebug/StikDebug"><img src="https://img.shields.io/badge/Ask-DeepWiki-grey?style=for-the-badge&labelColor=23272A&color=007ec6" /></a>
<br />
</h3>
## Features
- **JIT:** Enable Just In Time compilation for sideloaded apps that have the `get-task-allow` entitlement.
- **JIT:** Enable Just-In-Time compilation for sideloaded apps that have the `get-task-allow` entitlement.
- **App Launching:** Launch every app installed on your device.
- **Console:** Live app and system logs.
- **Scripts:** Manage automation scripts (mainly used for iOS 26 JIT).
@ -40,7 +33,7 @@
<h3 align="center">
<a href="https://altdirect.app/?url=https://stikdebug.xyz/index.json" target="_blank"><img src="https://altdirect.app/assets/png/AltSource_Blue.png" alt="Add AltSource" width="200"></a>
&nbsp;
<a href="https://github.com/StikDebug/StikDebug/releases/download/3.1.9/StikDebug-3.1.9.ipa" target="_blank"><img src="https://altdirect.app/assets/png/Download_Blue.png" alt="Download .ipa" width="200"></a>
<a href="https://github.com/StikDebug/StikDebug/releases/latest/download/StikDebug-3.1.15.ipa" target="_blank"><img src="https://altdirect.app/assets/png/Download_Blue.png" alt="Download .ipa" width="200"></a>
</h3>
## Compatibility
@ -69,12 +62,12 @@ StikDebug enables **JIT** for sideloaded apps on iOS 17.4+ without needing a com
- Launch LocalDevVPN and enable the VPN.
4. **Enable JIT for an app**
- Launch StikDebug and tapp the `Enable JIT` button.
- Launch StikDebug and tap the `Enable JIT` button.
- Select your sideloaded app from the list in StikDebug.
**Troubleshooting**
- "Connection dropped" or loopback errors → Check iOS version compatibility / beta warnings.
- Heartbeat errors → Ensure that the VPN is on and that you are connecected to Wi-Fi. It may be a pairing file issue.
- Heartbeat errors → Ensure that the VPN is on and that you are connected to Wi-Fi. It may be a pairing file issue.
- Pairing file issues → Replace file with device unlocked & trusted.
- Still stuck? Join the [Discord](https://discord.gg/ZnNcrRT3M8) with logs/screenshots.
@ -147,13 +140,11 @@ To propose a new feature, open a feature request issue and provide:
### Code Contributions (Best Practices)
- Follow normal Swift and SwiftUI style.
- Write clear and easy to understand code.
- Write clear and easy-to-understand code.
- Keep your changes consistent with how the project is already set up.
- Make sure everything builds and works without errors.
We appreciate your time and effort in helping improve this project.
## Code Help
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/StikDebug/stikdebug)
## License
StikDebug is licensed under **AGPL-3.0**. See [`LICENSE`](LICENSE) for details.

View file

@ -482,7 +482,7 @@
"$(PROJECT_DIR)/StikDebug/idevice",
);
MACOSX_DEPLOYMENT_TARGET = 15.1;
MARKETING_VERSION = 3.1.12;
MARKETING_VERSION = 3.1.15;
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -544,7 +544,7 @@
"$(PROJECT_DIR)/StikDebug/idevice",
);
MACOSX_DEPLOYMENT_TARGET = 15.1;
MARKETING_VERSION = 3.1.12;
MARKETING_VERSION = 3.1.15;
PRODUCT_BUNDLE_IDENTIFIER = com.stik.stikdebug;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View file

@ -39,7 +39,8 @@ private enum IdeviceBridge {
}
let code = Int(ffiError.pointee.code)
let message = string(from: ffiError.pointee.message) ?? fallback
let detail = string(from: ffiError.pointee.message) ?? fallback
let message = detail == fallback ? fallback : "\(fallback): \(detail)"
idevice_error_free(ffiError)
return makeError(domain: domain, code: code, message: message)
}
@ -264,45 +265,50 @@ private enum IdeviceBridge {
extension JITEnableContext {
func isDeveloperDiskImageMounted() throws -> Bool {
try IdeviceBridge.withTunnelHandles(for: self) { adapter, handshake in
var installed: UnsafeMutablePointer<InstalledCryptexC>?
let ffiError = cryptexd_installed_ddi(adapter, handshake, &installed)
let queryError = ffiError.map {
IdeviceBridge.consumeFFIError($0, fallback: "Failed to query installed DDI cryptex")
}
defer { cryptexd_free_installed_cryptex(installed) }
if installed != nil {
return true
var cryptexQuerySucceeded = false
var cryptexQueryError: NSError?
if DeveloperDiskImageService.usesCryptexDDI {
var installed: UnsafeMutablePointer<InstalledCryptexC>?
defer { cryptexd_free_installed_cryptex(installed) }
if let ffiError = cryptexd_installed_ddi(adapter, handshake, &installed) {
cryptexQueryError = IdeviceBridge.consumeFFIError(ffiError, fallback: "Failed to query installed DDI cryptex")
} else {
cryptexQuerySucceeded = true
if installed != nil {
return true
}
}
}
let legacyMounted = (try? IdeviceBridge.withConnectedClient(
fallback: "Failed to connect to image mounter",
missingClientMessage: "Image mounter client was not created",
connect: { image_mounter_connect_rsd(adapter, handshake, $0) },
cleanup: { image_mounter_free($0) }
) { client in
var devices: UnsafeMutablePointer<plist_t?>?
var deviceCount = 0
if let error = image_mounter_copy_devices(client, &devices, &deviceCount) {
throw IdeviceBridge.consumeFFIError(error, fallback: "Failed to fetch mounted devices")
}
if let devices {
for index in 0..<deviceCount {
plist_free(devices[index])
do {
return try IdeviceBridge.withConnectedClient(
fallback: "Failed to connect to image mounter",
missingClientMessage: "Image mounter client was not created",
connect: { image_mounter_connect_rsd(adapter, handshake, $0) },
cleanup: { image_mounter_free($0) }
) { client in
var devices: UnsafeMutablePointer<plist_t?>?
var deviceCount = 0
if let error = image_mounter_copy_devices(client, &devices, &deviceCount) {
throw IdeviceBridge.consumeFFIError(error, fallback: "Failed to fetch mounted devices")
}
idevice_data_free(
UnsafeMutableRawPointer(devices).assumingMemoryBound(to: UInt8.self),
UInt(deviceCount * MemoryLayout<plist_t?>.stride)
)
if let devices {
for index in 0..<deviceCount {
plist_free(devices[index])
}
idevice_data_free(
UnsafeMutableRawPointer(devices).assumingMemoryBound(to: UInt8.self),
UInt(deviceCount * MemoryLayout<plist_t?>.stride)
)
}
return deviceCount > 0
}
return deviceCount > 0
}) ?? false
if legacyMounted {
return true
} catch {
if cryptexQuerySucceeded {
return false
}
throw cryptexQueryError ?? (error as NSError)
}
if let queryError {
throw queryError
}
return false
}
}

View file

@ -117,7 +117,8 @@ final class JITEnableContext {
guard let ffiError else {
return makeError(fallback)
}
let message = nsString(from: ffiError.pointee.message, fallback: fallback)
let detail = nsString(from: ffiError.pointee.message, fallback: fallback)
let message = detail == fallback ? fallback : "\(fallback): \(detail)"
let error = makeError(message, code: Int(ffiError.pointee.code))
idevice_error_free(ffiError)
return error
@ -457,22 +458,19 @@ final class JITEnableContext {
private func withConnectedRemoteServer<T>(
_ body: (OpaquePointer) throws -> T
) throws -> T {
try ensureTunnel()
guard let adapter, let handshake else {
throw makeError("Tunnel is not connected")
}
try withFreshDebugTunnel(hostname: "StikDebugRemoteServer") { adapter, handshake in
var remoteServer: OpaquePointer?
if let ffiError = remote_server_connect_rsd(adapter, handshake, &remoteServer) {
throw error(from: ffiError, fallback: "Failed to connect remote server")
}
var remoteServer: OpaquePointer?
if let ffiError = remote_server_connect_rsd(adapter, handshake, &remoteServer) {
throw error(from: ffiError, fallback: "Failed to connect remote server")
}
guard let remoteServer else {
throw makeError("Remote server handle was not created")
}
guard let remoteServer else {
throw makeError("Remote server handle was not created")
defer { remote_server_free(remoteServer) }
return try body(remoteServer)
}
defer { remote_server_free(remoteServer) }
return try body(remoteServer)
}
private func withProcessControl<T>(

View file

@ -27,6 +27,7 @@ func checkMountStatus() -> MountCheckResult {
do {
return try JITEnableContext.shared.isDeveloperDiskImageMounted() ? .mounted : .notMounted
} catch {
LogManager.shared.addErrorLog("Failed to check DDI mount status: \(error.localizedDescription)")
return .unreachable
}
}

View file

@ -15,7 +15,7 @@ extension ScriptStore {
"Amethyst",
"MeloNX",
"XeniOS",
"MeloCafe",
"MeloCafé",
"Manic EMU",
"DukeX",
"TachyonU",
@ -23,7 +23,8 @@ extension ScriptStore {
"HyperHLE",
"Applesauce",
"RPCS3",
"AetherPS4"
"AetherPS4",
"Husk"
],
resource: ScriptResource(resourceName: "universal", fileName: "universal.js")
),

View file

@ -7,7 +7,7 @@ import SwiftUI
import UIKit
private enum SettingsLinks {
static let githubStars = URL(string: "https://github.com/StikDebug/StikDebug/stargazers")!
static let githubStars = URL(string: "https://github.com/StikDebug/StikDebug")!
static let pairingFileGuide = URL(string: "https://github.com/StikDebug/StikDebug-Guide/blob/main/pairing_file.md")!
static let localDevVPN = URL(string: "https://apps.apple.com/us/app/localdevvpn/id6755608044")!
static let discord = URL(string: "https://discord.gg/qahjXNTDwS")!