- 06 Sep, 2026 3 commits
-
-
Mahmoud Aglan authored
Two follow-ons from pinning AGP, both caught by build validation rather than at runtime, which is the argument against reaching for --android-skip-build-dependency-validation to make a build "pass". Kotlin: I had dropped it to 2.1.0 alongside the AGP pin, assuming AGP 8.x required it. It does not — KGP and AGP version independently, and Flutter 3.47 requires Kotlin >= 2.2.20, so my downgrade was the whole problem. Back to 2.4.0. There was no circular constraint here; there was an unnecessary edit. re_editor: 0.7.0 fails to compile against Flutter 3.47 — its _CodeInputController implements DeltaTextInputClient without onFocusReceived(), which the framework has since added. The caret constraint ^0.7.0 pinned it below 0.8, hiding the four newer releases; 0.10.0 implements it. Analysis stays clean across the upgrade, so no call sites changed. Final working combination: AGP 8.11.1 · Gradle 8.14 · Kotlin 2.4.0 · re_editor 0.10.0 Co-Authored-By:Claude Opus 5 (1M context) <noreply@anthropic.com>
-
Mahmoud Aglan authored
The release build failed while evaluating flutter_inappwebview_android: getDefaultProguardFile('proguard-android.txt') is no longer supported AGP 9 removed that API. The plugin still calls it at configuration time, in both its debug and release buildTypes, so the failure happens whether or not minification is on. 1.1.3 is the newest release of that plugin — 6.1.5 is the current top-level package — so there is nothing to upgrade to; the template simply pinned an AGP ahead of the plugin ecosystem. com.android.application 9.1.0 -> 8.7.3 kotlin.android 2.4.0 -> 2.1.0 (matched to AGP 8.x) gradle 9.3.1 -> 8.12 (AGP 8.7 does not support Gradle 9) Fixed here rather than by patching ~/.pub-cache: that cache is generated, shared between projects, outside git, and erased by `pub cache repair`. A fix there works on exactly one machine and silently disappears — including on the server, once Flutter moves into the Docker image. Reverse this pin when the plugin ships an AGP 9 build. The launcher icon is generated by a Pillow script from the same curve geometry as the in-app FlameMark painter, so the icon and the mark cannot drift apart. Co-Authored-By:Claude Opus 5 (1M context) <noreply@anthropic.com>
-
Mahmoud Aglan authored
Ground-up replacement for the DevPilot APK whose source was lost in the Sep 1 wipe. That app could only be maintained by guessing at an opaque binary: two days went into inferring its wire contract from `strings` on libapp.so, and the last bug (every text file rendering as "Binary file") was never solvable from the server side at all. Owning the source ends that entire class of problem. Five tabs, each backed by a real endpoint: VS Code code-server in a webview, host derived from the API host Chats multi-turn conversations, live SSE, per-message model and effort, attachments from the phone, local notification when a run lands Files project-scoped browser, re_editor with syntax highlighting, markdown rendered with mermaid diagrams, create/rename/delete/upload Git per-repo status, coloured diff, pull/commit/push Settings Claude usage against both rolling windows, connection, sign out Decisions worth recording: - models.dart parses defensively on purpose. Every fromJson is total and a wrong-typed field degrades to a default. The old client did the opposite and one bad field made *every* file unopenable, because a throw inside fromJson loses the whole object rather than one value. - Binary is believed only when the server explicitly says so. Treating "unknown" as binary is precisely the bug that made the previous app useless. - SSE is read off a raw HttpClient, not Dio: it is a line protocol held open indefinitely and Dio is built around a body that ends. The stream resumes with ?from=N so backgrounding the phone does not lose output. - Mermaid renders in a webview because no Dart package draws it; the source is passed as a JSON literal so quotes and newlines cannot break out, and it falls back to showing the source offline instead of an empty box. - Tabs live in an IndexedStack so scroll position, open directory and in-flight streams survive switching away — the app exists to leave work running. - No FCM. The server has nothing to push with, and the only event worth an interruption is one the app already observes. Co-Authored-By:Claude Opus 5 (1M context) <noreply@anthropic.com>
-