drukscode-v2/docs/developer/shell-sync.md
OpenCode AI e9899d2e6d
Some checks failed
Android CI Build / check (push) Has been cancelled
Android CI Build / package-apks (push) Has been cancelled
Docs Deploy / build (push) Has been cancelled
Module Market Check / Validate modules/ (push) Has been cancelled
Module Market Publish / Generate submissions.json (push) Has been cancelled
Docs Deploy / deploy (push) Has been cancelled
Initial DruksCode V2: fresh fork of web-to-app (f3b488e) with DruksCode identity
- Package rename com.webtoapp -> br.com.drukstech.codeapp
- Product rename WebToApp/web-to-app -> DruksCode/drukscode
- Design system Wta* -> Dkc*
- applicationId br.com.drukstech.codeapp (.play for gplay flavor)
- rootProject.name DruksCode
- Fresh git history (upstream kept as remote for sync)
2026-09-12 02:42:02 +02:00

2.7 KiB

Shell Sync & Template

Generated APKs run the shell runtime, whose Kotlin sources are synced from app/. Understanding this sync is essential: edit the wrong copy and your change either gets overwritten or silently diverges.

The rule

Shared runtime sources are authored in app/. Editing only a file under shell/src is usually wrong; it will be overwritten on sync or diverge from host.

What enters the shell

shell/build.gradle.kts defines a syncShellRuntimeSources task with an include/exclude list that selects the full runtime set from app/ (e.g. core/shell, core/webview, core/engine, core/extension, ui/shell). Shell-specific overrides live in shell/src/main/java-overrides/.

Building the template

./gradlew :shell:assembleRelease :app:syncShellTemplateApk --no-configuration-cache

This produces the single canonical template at app/src/main/assets/template/webview_shell.apk.

Concern Path
What enters shell shell/build.gradle.kts → syncShellRuntimeSources include/exclude
Shell template build :shell:assembleRelease + :app:syncShellTemplateApk
Template output app/src/main/assets/template/webview_shell.apk
Config → shell JSON app/.../apkbuilder/ApkConfigJsonFactory.kt
Shell config types app/.../core/shell/ShellModeManager.kt
Runtime WebView config app/.../ui/shell/ShellWebViewConfig.kt

The shell runtime entry

At runtime, a generated APK:

  1. DruksCodeApplication starts.
  2. ShellModeManager.isShellMode() checks for app_config.json in assets.
  3. If present, getConfig() deserializes it (via Gson) into ShellConfig — possibly decrypting it first.
  4. ShellServerLauncher resolves and launches server-backed runtimes; ShellRuntimeServices initializes the runtime stack.

Constraints

  • One shell template. Do not introduce a second template APK.
  • Low targetSdk (28). Required for fork+exec runtimes. Do not raise it casually.
  • Thin dependency set. Do not pull host-only deps into shell/build.gradle.kts.
  • Fail-soft notifications. FGS / notification channel creation must use SafeNotificationChannels; channel creation failures must not crash FGS startup.
  • Configuration-cache safety. Custom Gradle tasks (syncCloneHostDex, etc.) must capture File/Provider values at configuration time — do not reference Project/android.sdkDirectory inside task closures.

After changing shell membership

If you change what enters the shell or how the template is packaged, rebuild the template you touched. A stale template is one of the most frequent causes of "works in preview, broken after export."

./gradlew :shell:assembleRelease :app:syncShellTemplateApk --no-configuration-cache