Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
25a7ab4
potential apkm fix
prateek-who Jan 31, 2026
f92d1c9
Update PatchCommand.kt
prateek-who Jan 31, 2026
227bc14
Update .gitignore
prateek-who Jan 31, 2026
b2e63be
Update PatchCommand.kt
prateek-who Feb 1, 2026
ee63a14
feat: GUI Update
prateek-who Feb 6, 2026
d4ae84e
Removed hush hush svgs
prateek-who Feb 6, 2026
3c9c11a
Simplified version fixes + .apkm support fixed
prateek-who Feb 6, 2026
5199e5d
Minor UI updates
prateek-who Feb 6, 2026
73151ae
apkmirror link builder
prateek-who Feb 7, 2026
67a8aab
fix build
LisoUseInAIKyrios Feb 7, 2026
d30d4a5
Add IDE launcher preset
LisoUseInAIKyrios Feb 7, 2026
b6de86b
Use web-search api
LisoUseInAIKyrios Feb 7, 2026
afb8846
Follow redirects in non simple mode
LisoUseInAIKyrios Feb 7, 2026
3bfc223
Minor UI updates
prateek-who Feb 8, 2026
930d4b3
Connected devices update
prateek-who Feb 8, 2026
783dd7a
Patch Screen UI Improvements
prateek-who Feb 9, 2026
fdba2c6
--riplibs update
prateek-who Feb 9, 2026
ffa14f9
Minor release and windows fixes
prateek-who Feb 10, 2026
512f6f5
Patching Engine Fix
prateek-who Feb 11, 2026
bf224f6
Minor Fixes
prateek-who Feb 11, 2026
46a4577
Use non zero Java exit code if patching fails
prateek-who Feb 12, 2026
7640a80
Minor Fixes
prateek-who Feb 12, 2026
4477106
Merge remote-tracking branch 'origin/dev' into gui-update
LisoUseInAIKyrios Feb 15, 2026
5fb0e1a
Minor Fixes and new theme
prateek-who Feb 15, 2026
b8d3109
Better Offline support + Minor fixes
prateek-who Feb 19, 2026
7927c7e
Merge branch 'dev' into gui-update
prateek-who Feb 19, 2026
34eb844
Update PatchesViewModel.kt
prateek-who Feb 19, 2026
3648b94
Merge branch 'dev' into gui-update
prateek-who Feb 22, 2026
f3f80fc
conflict fix proper
prateek-who Feb 22, 2026
2cbb805
this for sure is the fix
prateek-who Feb 22, 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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ build/

# Local configuration file (sdk path, etc)
local.properties
old_build.gradle.kts

# Log/OS Files
*.log
Expand All @@ -23,6 +24,9 @@ misc.xml
deploymentTargetDropDown.xml
render.experimental.xml

# Kotlin
.kotlin/

# Keystore files
*.jks
*.keystore
Expand All @@ -33,5 +37,7 @@ google-services.json
# Android Profiling
*.hprof

# Mac files
.DS_Store
# NPM modules
node_modules/
9 changes: 9 additions & 0 deletions .run/CLI GUI.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="CLI GUI" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="app.morphe.MorpheLauncherKt" />
<module name="morphe-cli.main" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
124 changes: 107 additions & 17 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
alias(libs.plugins.kotlin)
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.compose)
alias(libs.plugins.shadow)
application
`maven-publish`
Expand All @@ -11,10 +13,33 @@ plugins {

group = "app.morphe"

// ============================================================================
// JVM / Kotlin Configuration
// ============================================================================
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(17))
vendor.set(JvmVendorSpec.ADOPTIUM)
}
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}

// ============================================================================
// Application Entry Point
// ============================================================================
// Shadow JAR reads this for Main-Class manifest attribute.
//
// No args / double-click → GUI (Compose Desktop)
// With args (terminal) → CLI (PicoCLI)
application {
mainClass = "app.morphe.cli.command.MainCommandKt"
mainClass.set("app.morphe.MorpheLauncherKt")
}

// ============================================================================
// Repositories
// ============================================================================
repositories {
mavenLocal()
mavenCentral()
Expand All @@ -23,15 +48,20 @@ repositories {
// A repository must be specified for some reason. "registry" is a dummy.
url = uri("https://maven.pkg.github.com/MorpheApp/registry")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")
password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN")
username = project.findProperty("gpr.user") as String?
?: System.getenv("GITHUB_ACTOR")
password = project.findProperty("gpr.key") as String?
?: System.getenv("GITHUB_TOKEN")
}
}
// Obtain baksmali/smali from source builds - https://github.com/iBotPeaches/smali
// Remove when official smali releases come out again.
maven { url = uri("https://jitpack.io") }
}

// ============================================================================
// Dependencies
// ============================================================================
val apkEditorLib by configurations.creating

val strippedApkEditorLib by tasks.registering(org.gradle.jvm.tasks.Jar::class) {
Expand All @@ -54,26 +84,59 @@ val strippedApkEditorLib by tasks.registering(org.gradle.jvm.tasks.Jar::class) {
dependencies {
api(libs.morphe.patcher)
implementation(libs.morphe.library)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.picocli)
apkEditorLib(files("$rootDir/libs/APKEditor-1.4.7.jar"))
implementation(files(strippedApkEditorLib))

// -- Compose Desktop ---------------------------------------------------
// Platform-independent: single JAR runs on all supported OSes.
// Skiko auto-detects the OS at runtime and loads the correct native library.
implementation(compose.desktop.macos_arm64)
implementation(compose.desktop.macos_x64)
implementation(compose.desktop.linux_x64)
implementation(compose.desktop.linux_arm64)
implementation(compose.desktop.windows_x64)
implementation(compose.components.resources)
@Suppress("DEPRECATION")
implementation(compose.material3)
implementation(compose.materialIconsExtended)

// -- Async / Serialization ---------------------------------------------
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.coroutines.swing)
implementation(libs.kotlinx.serialization.json)
// testImplementation(libs.kotlin.test)
//}

// -- Networking (GUI) --------------------------------------------------
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.cio)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.client.logging)

// -- DI / Navigation (GUI) ---------------------------------------------
implementation(platform(libs.koin.bom))
implementation(libs.koin.core)
implementation(libs.koin.compose)

implementation(libs.voyager.navigator)
implementation(libs.voyager.screenmodel)
implementation(libs.voyager.koin)
implementation(libs.voyager.transitions)

// -- APK Parsing (GUI) -------------------------------------------------
implementation(libs.apk.parser)

// -- Testing -----------------------------------------------------------
testImplementation(libs.kotlin.test)
testImplementation(libs.junit.params)
testImplementation(libs.mockk)
}

kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}

java {
targetCompatibility = JavaVersion.VERSION_11
}

// ============================================================================
// Tasks
// ============================================================================
tasks {
test {
useJUnitPlatform()
Expand All @@ -83,9 +146,15 @@ tasks {
}

processResources {
expand("projectVersion" to project.version)
// Only expand properties files, not binary files like PNG/ICO
filesMatching("**/*.properties") {
expand("projectVersion" to project.version)
}
}

// -------------------------------------------------------------------------
// Shadow JAR — the only distribution artifact
// -------------------------------------------------------------------------
shadowJar {
exclude(
"/prebuilt/linux/aapt",
Expand All @@ -95,14 +164,35 @@ tasks {
minimize {
exclude(dependency("org.bouncycastle:.*"))
exclude(dependency("app.morphe:morphe-patcher"))
// Compose / Skiko / Swing — cannot be minimized (reflection, native libs)
exclude(dependency("org.jetbrains.compose.*:.*"))
exclude(dependency("org.jetbrains.skiko:.*"))
exclude(dependency("org.jetbrains.kotlinx:kotlinx-coroutines-swing:.*"))
// Ktor uses ServiceLoader
exclude(dependency("io.ktor:.*"))
// Koin uses reflection
exclude(dependency("io.insert-koin:.*"))
}

mergeServiceFiles()
}

distTar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

distZip {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

publish {
dependsOn(shadowJar)
}
}

// ============================================================================
// Publishing / Signing
// ============================================================================
// Needed by gradle-semantic-release-plugin.
// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435

Expand Down
70 changes: 64 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,22 +1,80 @@
[versions]
# Core
shadow = "8.3.9"
junit = "5.11.0"
kotlin = "2.3.0"
kotlinx = "1.9.0"

# CLI
picocli = "4.7.7"
morphe-patcher = "1.2.0-dev.3" # TODO: change to 1.2.0 before stable release
morphe-library = "1.2.1-dev.1" # TODO: change to 1.2.1 before stable release

# Compose Desktop
compose = "1.10.0"

# Networking
ktor = "3.4.0"

# DI
koin-bom = "4.1.1"

# Navigation
voyager = "1.1.0-beta03"

# Async / Serialization
coroutines = "1.10.2"
kotlinx-serialization = "1.9.0"

# APK
apk-parser = "2.6.10"
arsclib = "1.3.8"

# Testing
mockk = "1.14.3"

[libraries]
# Morphe Core
junit-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx" }
picocli = { module = "info.picocli:picocli", version.ref = "picocli" }
morphe-patcher = { module = "app.morphe:morphe-patcher", version.ref = "morphe-patcher" }
morphe-library = { module = "app.morphe:morphe-library-jvm", version.ref = "morphe-library" }

# Ktor Client
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }

# Koin
koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koin-bom" }
koin-core = { module = "io.insert-koin:koin-core" }
koin-compose = { module = "io.insert-koin:koin-compose" }

# Voyager Navigation
voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" }
voyager-screenmodel = { module = "cafe.adriel.voyager:voyager-screenmodel", version.ref = "voyager" }
voyager-koin = { module = "cafe.adriel.voyager:voyager-koin", version.ref = "voyager" }
voyager-transitions = { module = "cafe.adriel.voyager:voyager-transitions", version.ref = "voyager" }

# Coroutines
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" }

# Serialization
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }

# APK
apk-parser = { module = "net.dongliu:apk-parser", version.ref = "apk-parser" }
arsclib = { module = "io.github.reandroid:ARSCLib", version.ref = "arsclib" }

# Testing
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }

[plugins]
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
compose = { id = "org.jetbrains.compose", version.ref = "compose" }
shadow = { id = "com.gradleup.shadow", version.ref = "shadow" }
13 changes: 13 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
pluginManagement {
repositories {
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
google()
mavenCentral()
gradlePluginPortal()
}
}

plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}

rootProject.name = "morphe-cli"

// Include morphe-patcher and morphe-library as composite builds if they exist locally
Expand Down
40 changes: 40 additions & 0 deletions src/main/composeResources/drawable/morphe_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading