Skip to content

Commit faba19b

Browse files
committed
Merge origin/stage into feat/ADFA-5047-java-extract-variable
No textual conflicts. One semantic one, resolved here: #1712 added JavaCodeActionTooltipTagTest, which asserts containsExactlyEntriesIn over every Java code action's id-to-tag map, so registering ExtractVariableAction in JavaCodeActionsMenu broke it. The action is added to that map, following the convention #1712 used for try/catch -- the tag is reserved ahead of its documentation.db row. #1712 also supersedes this branch's own JavaExtractVariableTooltipTagTest, which was deleted earlier; stage's version covers every Java action rather than just this one.
2 parents 43aa22c + 371a3ff commit faba19b

74 files changed

Lines changed: 6828 additions & 1738 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ sentry.properties
104104
.DS_Store
105105

106106
# Generated files for tooling API
107-
tests/test-home
108-
/tests/**/.cg/init/model.jar
109107

110108
/composite-builds/build-deps-common/constants/build/
111109
/composite-builds/build-deps/build/
@@ -193,3 +191,8 @@ NATIVE_*.md
193191
TEST_*.md
194192
assets-*.zip
195193
dynamic_libs/*.aar.br
194+
195+
# Per-project cache the IDE writes (models, sync metadata, locks). The test project's copy was
196+
# tracked and every test run rewrote it with the local machine's absolute paths, so it arrived in
197+
# unrelated commits -- a 12 MB binary among them (ADFA-5264).
198+
testing/resources/test-project/.cg/

ARCHITECTURE.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66

77
Code On The Go (CoGo) is a full Android IDE that runs **on the device** — it edits, builds, and deploys real Android apps offline, embedding a Termux toolchain and running an actual Gradle build in a separate process via the `tooling-api`. It is the maintained successor to AndroidIDE, so the codebase namespace is still `com.itsaky.androidide`.
88

9-
There is **no single architectural philosophy** across the whole app. This large, layered application is still **predominantly View-based**: newer feature surfaces (plugin manager, AI agent, git, project list) follow a deliberate **Unidirectional Data Flow (UDF)** with Koin DI, `ViewModel` + `StateFlow`, sealed UI-state/effect types, and repositories, while older surfaces still use `LiveData` and talk to GreenRobot EventBus directly. New work follows the UDF pattern documented below, and new UI is built in **Jetpack Compose** ([ADR 0009](docs/adr/0009-jetpack-compose-for-new-ui.md)) — Compose replaces the view layer only; the UDF stack (ViewModel + `StateFlow`, Koin, repositories) is unchanged. Existing XML/View screens remain until substantially reworked.
9+
There is **no single architectural philosophy** across the whole app. This large, layered application is still **predominantly View-based**: newer feature surfaces (plugin manager, AI agent, git, project list) follow a deliberate **Unidirectional Data Flow (UDF)** with Koin DI, `ViewModel` + `StateFlow`, sealed UI-state/effect types, and repositories, while older surfaces still use `LiveData` and talk to GreenRobot EventBus directly. New work follows the UDF pattern documented below, and new UI is built in **Jetpack Compose** ([ADR 0009](docs/adr/0009-jetpack-compose-for-new-ui.md)) — Compose replaces the view layer only; the UDF stack (ViewModel + `StateFlow`, Koin, repositories) is unchanged. Existing XML/View screens remain until substantially reworked. The first production example is the **Manager** screen (`PluginManagerActivity`) — merged Plugins/Templates tabs built with `Scaffold`/`TabRow`/`HorizontalPager` (ADFA-4928).
1010

1111
## Core Architecture & Data Flow
1212

13-
Feature code layers as **UI → ViewModel → Repository → data source**, with state flowing up and events/intents flowing down. Koin provides dependencies (`coreModule`, `pluginModule`), constructor-injected into ViewModels.
13+
Feature code layers as **UI → ViewModel → Repository → data source**, with state flowing up and events/intents flowing down. Koin provides dependencies (`coreModule`, `pluginModule`, `templateModule`), constructor-injected into ViewModels.
1414

1515
- **Data sources** — Room (`RecentProjectRoomDatabase` + DAO, `suspend` functions), raw SQLite (`SQLiteOpenHelper`, e.g. `localWebServer/WebServer`), the filesystem/preferences, the embedded `tooling-api` (on-device Gradle), and external clients (Gemini via the Google GenAI SDK, on-device llama.cpp, JGit). Most are exposed through `suspend` functions.
16-
- **Repositories** — e.g. `agent/repository/GeminiRepository`, `repositories/PluginRepository`, `repositories/BreakpointRepository`. They wrap data sources and hide threading/IO from the ViewModel.
16+
- **Repositories** — e.g. `agent/repository/GeminiRepository`, `repositories/PluginRepository`, `repositories/TemplateRepository`, `repositories/BreakpointRepository`. They wrap data sources and hide threading/IO from the ViewModel.
1717
- **ViewModels** — run work in `viewModelScope` on `Dispatchers.IO`, hold a private `MutableStateFlow`/`MutableSharedFlow`, and expose read-only `StateFlow`/`SharedFlow`. One-shot effects (toasts, navigation, dialogs) go through a separate `SharedFlow` of a sealed `*UiEffect` type.
18-
- **UI (Fragments / Activities / Views)** — collect state in a lifecycle-aware coroutine and render it; user actions return to the ViewModel as method calls or sealed `*UiEvent` intents. The existing UI is **Android Views + Fragments + RecyclerView adapters**; new UI is Jetpack Compose ([ADR 0009](docs/adr/0009-jetpack-compose-for-new-ui.md)). (`compose-preview` previews the *user's* Compose code, not CoGo's own.)
18+
- **UI (Fragments / Activities / Views)** — collect state in a lifecycle-aware coroutine and render it; user actions return to the ViewModel as method calls or sealed `*UiEvent` intents. The existing UI is **Android Views + Fragments + RecyclerView adapters**; new UI is Jetpack Compose ([ADR 0009](docs/adr/0009-jetpack-compose-for-new-ui.md)) — first used in the Manager screen (`ui/compose/ManagerScreen.kt`, ADFA-4928). (`compose-preview` previews the *user's* Compose code, not CoGo's own.)
1919

2020
```
2121
┌─────────────────────────────────────────────┐
@@ -83,14 +83,14 @@ These structural facts shape every module. Day-to-day build *commands* live in `
8383
- **SDK levels** (`build-logic/.../build/config/BuildConfig.kt`): `COMPILE_SDK=36`, `MIN_SDK=28`, `TARGET_SDK=28`. **`TARGET_SDK` is deliberately pinned at 28:** higher targets enforce W^X (write-xor-execute), which blocks executing code from app-writable files. That is fatal for an on-device IDE that compiles and runs code (Gradle, `javac`, Termux binaries), so it is a hard requirement, not tech debt. `MIN_SDK_FOR_APPS_BUILT_WITH_COGO=16` is the floor for the apps a *user* builds with CoGo — distinct from CoGo's own `MIN_SDK`.
8484
- **Native asset bundling.** The on-device LLM (`llama-impl`) ships as a per-flavor native AAR, wired through the root `build.gradle.kts` (`bundleLlamaV8Assets` / `assembleV8Assets`, …); prebuilt per-flavor assets live under `assets/release/v7/` and `assets/release/v8/`.
8585
- **Native lib compression** (ADFA-2306, ADFA-4729). The app manifest hard-codes `android:extractNativeLibs="true"` (required: the installer must materialize libs in `nativeLibraryDir`, e.g. `libshizuku.so` is an executable the adb shell runs from there). That attribute overrides the `jniLibs.useLegacyPackaging` DSL, so AGP packages `lib/<abi>/*.so` deflate-compressed in **every** APK — ~5.9 MB smaller (`libtree-sitter-kotlin.so` alone is 4.18 MB → 339 kB). The trap is the `recompressApk` post-step (release always, debug in CI only): its no-compress lists in `app/build.gradle.kts` must NOT contain `"so"`, or it silently re-stores the libs and undoes the saving — which is what ADFA-2306 fixed for release and ADFA-4729 for CI debug. Locally built debug APKs (including the e2e farm's) never run that step and were always fine.
86-
- **`app` package layout is by concern, not feature:** `activities`, `fragments`, `services`, `di`, `agent`, `viewmodel(s)`, `repositories`, `roomData`, `localWebServer`, `preferences`, `ui`, `utils`, ….
86+
- **`app` package layout is by concern, not feature:** `activities`, `fragments`, `services`, `di`, `agent`, `viewmodel(s)`, `repositories`, `roomData`, `localWebServer`, `preferences`, `ui` (Compose screens live under `ui/compose`), `templates/manager` (the Manager screen's `.cgt`-parsing data layer, with direct filesystem access to `Environment.TEMPLATES_DIR` — distinct from the plugin-facing `IdeTemplateService` in `plugin-api`/`plugin-manager`), `utils`, ….
8787

8888
## Technology Stack
8989

9090
| Concern | Library / Approach |
9191
|---|---|
92-
| UI | **Jetpack Compose for all new UI** ([ADR 0009](docs/adr/0009-jetpack-compose-for-new-ui.md)). The existing majority is still Android Views + Fragments + `RecyclerView` (Material Components); those legacy screens stay until reworked, but new IDE UI is Compose-only. |
93-
| Dependency Injection | **Koin** (`org.koin`) — `coreModule`/`pluginModule`, `startKoin` in `IDEApplication`, plus a `ServiceLocator : KoinComponent` for lazy post-startup access. No Hilt/Dagger. |
92+
| UI | **Jetpack Compose for all new UI** ([ADR 0009](docs/adr/0009-jetpack-compose-for-new-ui.md)); first production screen is the Manager screen (Plugins/Templates tabs, `app/.../ui/compose/`, ADFA-4928). The existing majority is still Android Views + Fragments + `RecyclerView` (Material Components); those legacy screens stay until reworked, but new IDE UI is Compose-only. |
93+
| Dependency Injection | **Koin** (`org.koin`) — `coreModule`/`pluginModule`/`templateModule`, `startKoin` in `IDEApplication`, plus a `ServiceLocator : KoinComponent` for lazy post-startup access. No Hilt/Dagger. |
9494
| Asynchronous work | **Kotlin Coroutines + Flow** (`StateFlow`/`SharedFlow`, `viewModelScope`, app-scoped `CoroutineScope(SupervisorJob() + Dispatchers.IO)`); **GreenRobot EventBus** for cross-subsystem events. |
9595
| Networking | Offline-first; no general REST layer. External I/O is **Google GenAI SDK** (Gemini), **on-device llama.cpp**, and **JGit** (git). Retrofit is in the catalog but effectively unused in app code. |
9696
| Database / Persistence | **Room** is the default for relational/queryable data; **filesystem + preferences (DataStore)** for non-relational settings. **Raw SQLite** (`SQLiteDatabase` / `SupportSQLiteOpenHelper`) only for justified exceptions (see policy below). |

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515

1616
<p align="center">
1717
<a href="https://github.com/appdevforall/CodeOnTheGo/issues">Report a bug or request a feature</a> &nbsp; &#8226; &nbsp;
18-
<a href="https://github.com/appdevforall/CodeOnTheGo/discussions">Join our support and discussions forum</a>&nbsp; &#8226; &nbsp;
19-
<a href="https://t.me/CodeOnTheGoOfficial">Telegram channel</a>
18+
<a href="https://github.com/appdevforall/CodeOnTheGo/discussions">Support and discussions forum</a>&nbsp; &#8226; &nbsp;
19+
<a href="https://t.me/CodeOnTheGoOfficial">Telegram channel</a> &nbsp; &#8226; &nbsp;
20+
<a href="https://github.com/appdevforall/CodeOnTheGo/wiki/Code-on-the-Go-Knowledge-Base">Knowledge base</a>
2021
</p>
2122

2223
## Code on the Go and AndroidIDE

actions/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ dependencies {
4444

4545
implementation(libs.androidx.core.ktx)
4646
implementation(libs.google.material)
47+
testImplementation(projects.testing.unit)
4748
}

0 commit comments

Comments
 (0)