diff --git a/AGENTS.md b/AGENTS.md index 87292fc..57972a5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,19 +20,26 @@ is a new driver — never a session-type branch in shared code (routes, transcript, app screens). The second one, for the Rust port on the `rustify` branch: **the phone app -and a planned desktop app share almost all of their code.** Screens, widgets, -folding, paging, config and the network client live in the shared crates -(`iris`, `client-core`, `transcript-ui`, `tabs-ui`); `android-app` and -`desktop-app` are thin entry points that own only what the platform forces -(JNI and the IME on one side, winit and argv on the other). The two +and a planned desktop app share almost all of their code.** Screens, +widgets, folding, paging, config and the network client live in +`app-rust/`'s `client` and `ui` modules, drawn with `iris`; `src/android` +and `src/desktop` are thin entry points that own only what the platform +forces (JNI and the IME on one side, winit and argv on the other). The two *layouts* will differ, to suit a phone's screen and a finger against a desktop's screen and a mouse -- but the widgets a layout is made of (a button, a text field, a list, a card) and the styling (colours, spacing, type) are one implementation with no per-platform copy. Anything that could -work on both goes in a shared crate the first time it is written, and a -platform crate growing a widget or a colour is a defect to move, not a -convenience to keep. Iris said this on 2026-09-07; docs/RUST.md carries the -details. +work on both goes in `ui` the first time it is written, and a platform +module growing a widget or a colour is a defect to move, not a convenience +to keep. Iris said this on 2026-09-07; docs/RUST.md carries the details. + +The third, from Iris on 2026-09-08: **`iris/` is the UI framework and +nothing else.** Nothing in it may know about a session, a transcript, a +setup or a server; anything that does belongs in `app-rust/`, and the +dependency runs one way only. The port's project code is **one crate** +(`ai-app`) rather than the six it was scattered across — see docs/RUST.md's +"One app crate" for what forced each of the splits that were removed and +the two that remain. ## Layout @@ -44,6 +51,22 @@ Module-by-module intent is in `docs/PLAN.md`'s "Backend layout". - `server/` — the Rust backend (`ai-server`). `routes.rs`'s module doc comment is the HTTP table and the surface's source of truth. +- `event-model/` — the wire shape `server/` and `app-rust/` both depend on, + which is the whole reason it is a crate of its own rather than part of + either: it is the contract between them, so the two agree by construction. +- `app-rust/` — the Rust app, one crate (`ai-app`) with three faces. `src/ + client` is everything with no UI in it (the REST and SSE clients, the + transcript cache and fold, the highlighter, the ANSI parser, config and + the enrolment link); `src/ui` is the screens as iris widget trees; + `src/desktop` + `src/bin_desktop.rs` is the winit binary; `src/android` + is the `android-view` entry point and `android-project/` its Gradle app; + `src/shell` is the separate JNI bridge the Kotlin `app/shellApp` calls. + Features pick which face a build is: `screens` (default) for anything + that draws, `shell` for the Compose app's bridge, `bench` for P0's + fixture build. See its `Cargo.toml` header. +- `iris/` — the UI framework, and **only** the UI framework: `core`, + `macro`, the `iris` crate itself, `tabs-ui` (its own demo widget tree) + and `rig-input`. It must not mention anything this product is about. - `app/` — the Compose app, package `com.example.aiapp`, label "AI Sessions". `AppRoot.kt` is the navigation `when`; `MainScreen.kt` the root's four tabs (sessions, import, models, setups); `Api.kt`/`EventStream.kt` the REST + SSE @@ -66,6 +89,9 @@ Module-by-module intent is in `docs/PLAN.md`'s "Backend layout". Read it before touching `TranscriptCache.kt`, `TranscriptSource.kt`, or the opening and stream effects in `SessionScreen.kt`. - `docs/TODO.md` — the working list. + - `docs/SUBAGENTS.md` and `docs/SUBAGENTS_DECISIONS.md` — a session's + subagents (the wire shape, the phone's view) and the choices behind + them still awaiting review. - `docs/RUST.md` — the plan for moving the app to Rust (on the `rustify` branch of the `ai-app-2` clone): what has to be reproduced, the framework decision, and the ordered experiments with their pass @@ -74,8 +100,8 @@ Module-by-module intent is in `docs/PLAN.md`'s "Backend layout". `docs/LAYOUT.md`, `docs/TEXTURES.md`, `docs/CLIENT_CORE.md` — iris's own build log (**any major addition or design decision, not only public API** -- Iris, 2026-09-08), working list, decisions log, - layout/render design, and texture-atlas design, and the client-core - crate's design, respectively. + layout/render design, texture-atlas design, and the design of + `app-rust`'s `client` module, respectively. - `docs/SCROLL.md` — how anything in iris scrolls: one `ScrollController` holds the position, the gesture, the fling and the pin, and the two widgets that scroll (`ScrollArea`, `LazySpan`) own @@ -121,10 +147,15 @@ guaranteed to have. ## Checking your work -- **Server**: `./run-tests.sh` from the repo root (or `cargo test` from - `server/`), plus `cargo clippy --all-targets` and `cargo fmt`. The build - stays warning-clean and rustfmt-clean at the defaults — there is no - `rustfmt.toml` and there should not be one. +- **Rust**: `./run-tests.sh` from the repo root runs `event-model`, + `server/` and `app-rust/`; `cd iris && cargo test` runs the framework's + own suite, which is slower and not about this product. Each workspace + also gets `cargo clippy --all-targets` and `cargo fmt`. The build stays + warning-clean and rustfmt-clean at the defaults — there is no + `rustfmt.toml` and there should not be one. `app-rust/` and `iris/` are + pinned to the same dated nightly (`rust-toolchain.toml`, one copy each, + because a pin applies per directory); `server/` and `event-model/` are + stable. - **App**: from `app/`, `. ./android-env.sh && ./gradlew :androidApp:ktfmtFormat :androidApp:compileDebugKotlin :androidApp:lintDebug @@ -295,25 +326,30 @@ Each exists because something was invisible without it. framework, from `atrace` text output with no trace processor needed. It is how the cost of a layout node per link was attributed to the framework rather than guessed at. -- **`iris/android-app/build-apk.sh [debug|release] [--abi ...] [--features - ...]`** builds iris-android-app's cdylib (`cargo ndk`) and its APK - (Gradle) in one step and verifies the result (`aapt2`/`apksigner`), and - **`iris/android-app/run-bench.sh [--apk PATH]`** installs it on this - checkout's own emulator, taps "Run benchmark" by label, and prints the - report -- written so the P0 build/install/tap/read-report cycle stops - being retyped by hand each time (docs/RUST.md's P0 box). +- **`app-rust/build-apk.sh [debug|release] [--abi ...] [--features + ...]`** builds the Rust app's cdylib (`cargo ndk` from `app-rust/`, + straight into `android-project/app/src/main/jniLibs/`) and its APK + (Gradle, from `android-project/`) in one step and verifies the result + (`aapt2`/`apksigner`), and **`app-rust/run-bench.sh [--apk PATH]`** + installs it on this checkout's own emulator, taps "Run benchmark" by + label, and prints the report -- written so the P0 + build/install/tap/read-report cycle stops being retyped by hand each + time (docs/RUST.md's P0 box). It passes `--no-default-features`, so + `--features` alone decides what is in the `.so`; that is what keeps the + 1.9 MB bench fixture out of a build that did not ask for `bench`. - **iris's three test layers** (docs/RUST.md's "Three test layers" has the commands and what each cannot answer): test at the cheapest one - that can answer the question. `cargo test -p transcript-fixture` runs - the real transcript screen over the bench fixture with **no window, no + that can answer the question. `cd app-rust && cargo test` runs the real + transcript screen over the bench fixture with **no window, no compositor and no GPU** (`iris::harness`), on a clock the test owns and a gesture replayed from a `t_ms action x y` file under - `iris/transcript-fixture/touch/` -- which is how the batched 120Hz + `app-rust/touch/` -- which is how the batched 120Hz flick a finger actually makes is testable at all, since a `ui-trace` swipe is many evenly-spaced events. `iris/run-headless.sh phone --phone - --shot …` opens the same screen in a window at the phone's own size and - density for looking at, and `--replay FILE` drives the same recording - into it. The emulator is for JNI, the IME, insets, the surface + --dir ../app-rust --shot …` opens the same screen in a window at the + phone's own size and density for looking at, and `--replay FILE` drives + the same recording into it (`--dir` names the workspace to build in, + since the rig lives in iris and the app's examples do not). The emulator is for JNI, the IME, insets, the surface lifecycle and one verification run before a build goes to the phone -- not for iterating on layout. - **The emulator is a GLES rig, deliberately** (Iris, 2026-09-08; diff --git a/android-shell/Cargo.lock b/android-shell/Cargo.lock deleted file mode 100644 index 8d98ec4..0000000 --- a/android-shell/Cargo.lock +++ /dev/null @@ -1,1130 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aho-corasick" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" -dependencies = [ - "memchr", -] - -[[package]] -name = "android-shell" -version = "0.1.0" -dependencies = [ - "android_logger", - "client-core", - "jni", - "log", -] - -[[package]] -name = "android_log-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" - -[[package]] -name = "android_logger" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3" -dependencies = [ - "android_log-sys", - "env_filter", - "log", -] - -[[package]] -name = "base64" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" - -[[package]] -name = "bitflags" -version = "2.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" - -[[package]] -name = "bytes" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" - -[[package]] -name = "cc" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "client-core" -version = "0.1.0" -dependencies = [ - "base64", - "event-model", - "log", - "pulldown-cmark", - "serde", - "serde_json", - "ureq", -] - -[[package]] -name = "combine" -version = "4.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "cookie" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "cookie_store" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" -dependencies = [ - "cookie", - "document-features", - "idna", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "time", - "url", -] - -[[package]] -name = "crc32fast" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" - -[[package]] -name = "displaydoc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.5", -] - -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - -[[package]] -name = "env_filter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "event-model" -version = "0.1.0" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" - -[[package]] -name = "flate2" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" -dependencies = [ - "crc32fast", - "miniz_oxide", - "zlib-rs", -] - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "getopts" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "hashbrown" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" - -[[package]] -name = "http" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "icu_collections" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" - -[[package]] -name = "icu_properties" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" - -[[package]] -name = "icu_provider" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "jni" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" -dependencies = [ - "cfg-if", - "combine", - "jni-macros", - "jni-sys", - "log", - "simd_cesu8", - "thiserror", - "walkdir", - "windows-link", -] - -[[package]] -name = "jni-macros" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" -dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "simd_cesu8", - "syn 2.0.119", -] - -[[package]] -name = "jni-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" -dependencies = [ - "jni-sys-macros", -] - -[[package]] -name = "jni-sys-macros" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" -dependencies = [ - "quote", - "syn 2.0.119", -] - -[[package]] -name = "libc" -version = "0.2.189" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" - -[[package]] -name = "litemap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" - -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - -[[package]] -name = "log" -version = "0.4.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" - -[[package]] -name = "memchr" -version = "2.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" - -[[package]] -name = "miniz_oxide" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "num-conv" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "potential_utf" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "proc-macro2" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "pulldown-cmark" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" -dependencies = [ - "bitflags", - "getopts", - "memchr", - "pulldown-cmark-escape", - "unicase", -] - -[[package]] -name = "pulldown-cmark-escape" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" - -[[package]] -name = "quote" -version = "1.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "regex" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustls" -version = "0.23.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6725596c3f2c3a0aef021139e145d4eafe314a6623e4680ca83852b2c67ab2ba" -dependencies = [ - "log", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pki-types" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - -[[package]] -name = "serde" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.229" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.5", -] - -[[package]] -name = "serde_json" -version = "1.0.151" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "shlex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" - -[[package]] -name = "simd-adler32" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" - -[[package]] -name = "simd_cesu8" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" -dependencies = [ - "rustc_version", - "simdutf8", -] - -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] -name = "smallvec" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.119" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "3.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "thiserror" -version = "2.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.5", -] - -[[package]] -name = "time" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" - -[[package]] -name = "time-macros" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "unicase" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "ureq" -version = "3.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af5546be8f5378d5414f83733f5c9a2526f4645829edbc1c41790aeef1b38e8b" -dependencies = [ - "base64", - "cookie_store", - "flate2", - "log", - "percent-encoding", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "ureq-proto", - "utf8-zero", - "webpki-roots", -] - -[[package]] -name = "ureq-proto" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabc3e92916c89c95b20eef7b06b00b066bc217ef9ea3a4ac9bf1a7e35261e10" -dependencies = [ - "base64", - "http", - "httparse", - "log", -] - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8-zero" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "webpki-roots" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "writeable" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" - -[[package]] -name = "yoke" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", - "synstructure", -] - -[[package]] -name = "zerofrom" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" - -[[package]] -name = "zerotrie" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.5", -] - -[[package]] -name = "zlib-rs" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12" - -[[package]] -name = "zmij" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/android-shell/Cargo.toml b/android-shell/Cargo.toml deleted file mode 100644 index 3758acd..0000000 --- a/android-shell/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "android-shell" -version = "0.1.0" -edition = "2024" - -# The JNI bridge behind E3's two Java stub classes (`MainActivity`, -# `NotificationService` -- see RUST.md's "How much Java is unavoidable" for -# why those two classes cannot be anything but Java/Kotlin, registered from -# the manifest by name). Everything they would otherwise have done in -# Kotlin -- the SSE follow loop, deciding where a notification is shown, -# picking a session for a share -- is here instead, built on `client-core` -# so the networking and parsing are not duplicated a third time next to the -# server and the Kotlin app. -# -# `cdylib` for `System.loadLibrary`; `lib` too so `cargo test`/`clippy` run -# on a normal host target without an Android NDK toolchain, the same -# posture `client-core` and `server` already have. - -[lib] -name = "android_shell" -crate-type = ["cdylib", "lib"] - -[dependencies] -client-core = { path = "../client-core" } -jni = "0.22" -log = "0.4" - -# `LogErrorAndDefault` (the `native_method!` error policy this crate uses -# throughout, see lib.rs) logs through the `log` facade, which is a no-op -# without a backend installed -- so without this, every recoverable error -# at a native entry point would be silently dropped rather than reaching -# logcat. Android-only: nothing else here needs it, and it does not build -# off-device (see `notify::ensure_logger`'s call site, the only place this -# is used). -[target.'cfg(target_os = "android")'.dependencies] -android_logger = "0.15" diff --git a/app-rust/.gitignore b/app-rust/.gitignore new file mode 100644 index 0000000..ff375e7 --- /dev/null +++ b/app-rust/.gitignore @@ -0,0 +1,10 @@ +android-project/.gradle/ +android-project/build/ +android-project/app/build/ + + +# Rebuilt by `cargo ndk -o app/src/main/jniLibs/ build` before every +# Gradle build -- see RUST.md's I2 for the exact command. +android-project/app/src/main/jniLibs/ +target/ +Cargo.lock.orig diff --git a/iris/android-app/Cargo.lock b/app-rust/Cargo.lock similarity index 98% rename from iris/android-app/Cargo.lock rename to app-rust/Cargo.lock index ed982b9..7d3161f 100644 --- a/iris/android-app/Cargo.lock +++ b/app-rust/Cargo.lock @@ -166,6 +166,28 @@ dependencies = [ "memchr", ] +[[package]] +name = "ai-app" +version = "0.1.0" +dependencies = [ + "android-view", + "android_logger", + "base64", + "event-model", + "iris", + "jni 0.22.4", + "libc", + "log", + "pulldown-cmark", + "serde", + "serde_json", + "tabs-ui", + "tempfile", + "tokio", + "ureq", + "winit", +] + [[package]] name = "aligned" version = "0.4.3" @@ -743,19 +765,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" -[[package]] -name = "client-core" -version = "0.1.0" -dependencies = [ - "base64", - "event-model", - "log", - "pulldown-cmark", - "serde", - "serde_json", - "ureq", -] - [[package]] name = "clipboard-win" version = "5.4.1" @@ -881,9 +890,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -891,18 +900,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.20" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -1055,7 +1064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1167,9 +1176,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "font-types" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64eb721ca85a34323425f4041adc5d82704d3782d5f8f03793bc012419dce23" +checksum = "b8eb065f3251655b3c90e22e5e363f310fc5332fb3402e37bbc94752283248f6" dependencies = [ "bytemuck", ] @@ -1718,24 +1727,6 @@ dependencies = [ "winit", ] -[[package]] -name = "iris-android-app" -version = "0.1.0" -dependencies = [ - "android-view", - "android_logger", - "client-core", - "event-model", - "iris", - "libc", - "log", - "serde_json", - "tabs-ui", - "tokio", - "transcript-fixture", - "transcript-ui", -] - [[package]] name = "iris-core" version = "0.1.0" @@ -1943,7 +1934,7 @@ dependencies = [ "bitflags 2.13.1", "libc", "plain", - "redox_syscall 0.9.3", + "redox_syscall 0.9.4", ] [[package]] @@ -2599,7 +2590,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3173,9 +3164,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d678d17679829e73d371e96880897e98fee2ded7acc0a50bdf8af2affa4b2fe5" +checksum = "737970939a87c6fa31e7acad13307bccbb017a073b695b6089a2c484f929e20e" dependencies = [ "bitflags 2.13.1", ] @@ -3282,14 +3273,14 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.43" +version = "0.23.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" +checksum = "6725596c3f2c3a0aef021139e145d4eafe314a6623e4680ca83852b2c67ab2ba" dependencies = [ "log", "once_cell", @@ -3638,7 +3629,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix 1.1.4", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3840,28 +3831,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "transcript-fixture" -version = "0.1.0" -dependencies = [ - "client-core", - "event-model", - "iris", - "serde_json", - "transcript-ui", -] - -[[package]] -name = "transcript-ui" -version = "0.1.0" -dependencies = [ - "client-core", - "event-model", - "iris", - "log", - "pulldown-cmark", -] - [[package]] name = "tree_magic_mini" version = "3.2.2" @@ -3887,7 +3856,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3932,9 +3901,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972d7902c8735f2695410b8aed7df6ed12a47394aa1c8d7af49f0497b731a94d" +checksum = "af5546be8f5378d5414f83733f5c9a2526f4645829edbc1c41790aeef1b38e8b" dependencies = [ "base64", "cookie_store", @@ -3952,9 +3921,9 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da5f78b09e6941e1a0f2e30e695e4b120377b54d5e0aec11b594bb57b3971613" +checksum = "fabc3e92916c89c95b20eef7b06b00b066bc217ef9ea3a4ac9bf1a7e35261e10" dependencies = [ "base64", "http", @@ -4417,7 +4386,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5075,18 +5044,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.56" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.56" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", diff --git a/app-rust/Cargo.toml b/app-rust/Cargo.toml new file mode 100644 index 0000000..a759027 --- /dev/null +++ b/app-rust/Cargo.toml @@ -0,0 +1,154 @@ +# The app: everything that is about *this product* rather than about the UI +# framework it draws with. One package, because splitting it was buying +# nothing -- see `docs/RUST.md`'s "One app crate" for the account. In short: +# `client` (the REST/SSE clients, the transcript cache and fold, the +# highlighter) and `ui` (the screens, in iris widgets) only ever ship +# together, and the three entry points below are three faces of one binary +# rather than three programs. +# +# `iris/` is the framework and knows nothing about any of this; the +# dependency runs one way, and a widget or a colour appearing here that is +# not about a session, a transcript or a setup belongs there instead +# (AGENTS.md). +[package] +name = "ai-app" +version = "0.1.0" +edition = "2024" + +# `cdylib` is the Android face -- both the iris app (`android-project/`, +# `System.loadLibrary("ai_app")`) and the JNI bridge the Kotlin shell in +# `app/shellApp` calls (the `shell` feature). `rlib` is what the desktop +# binary, the examples and `tests/` link against. One package produces one +# library artifact, so the two Android apps share a `.so` name and pick +# what goes in it with features rather than with a second crate. +[lib] +name = "ai_app" +crate-type = ["cdylib", "rlib"] + +[[bin]] +name = "ai-app-desktop" +path = "src/bin_desktop.rs" +required-features = ["screens"] + +[[example]] +name = "transcript" +required-features = ["screens"] + +[[example]] +name = "phone" +required-features = ["fixture"] + +[dependencies] +# The event model, shared with `server/` so the two agree by construction. +# It stays a crate of its own at the repo root for exactly that reason: +# it is the contract between this app and the backend, not app code. +event-model = { path = "../event-model" } +serde = { version = "1", features = ["derive"] } +# `float_roundtrip` for the same reason `server/` sets it -- AGENTS.md's +# "Things that have bitten". `raw_value` for the transcript cache. +serde_json = { version = "1", features = ["float_roundtrip", "raw_value"] } +ureq = { version = "3", features = ["json"] } +pulldown-cmark = "0.13.4" +base64 = "0.23" +log = { version = "0.4.34", features = ["std"] } + +# The UI framework. Optional so `--no-default-features --features shell` +# builds the Kotlin shell's JNI bridge without linking wgpu, parley and +# the rest of a renderer into an APK that draws with Compose. +iris = { path = "../iris", optional = true } +# iris's own tabs demo, kept runnable on Android through this project's +# Gradle app (the `tabs-screen` feature). The dependency direction is the +# right way round: the app may reach into the framework's example widget +# tree, never the reverse. +tabs-ui = { path = "../iris/tabs-ui", optional = true } +jni = { version = "0.22", optional = true } +# `bench` only: `libc` for the process CPU-time and RSS samples, `tokio` +# for the run's own timer. +libc = { version = "0.2.189", optional = true } +tokio = { version = "1.53.1", features = ["rt", "time"], optional = true } + +[target.'cfg(not(target_os = "android"))'.dependencies] +winit = "0.30.13" + +# Pinned to the exact commit RUST.md's E1 measured on this emulator; see +# `iris/Cargo.toml`'s copy of this pin for what advancing it costs. +[target.'cfg(target_os = "android")'.dependencies] +android-view = { git = "https://github.com/rust-mobile/android-view.git", rev = "bec6c62a96cef8239b0fd7fedeef9b184d02e3a1" } +android_logger = "0.15.1" + +[features] +default = ["screens", "fixture"] +# The iris half: `src/ui` and everything that draws. Off for the Kotlin +# shell's bridge, which is JNI and `src/client` only. +screens = ["dep:iris"] +# `src/ui/fixture.rs` and the harness tests that drive it. Default-on so +# `cargo test` covers them; `build-apk.sh` passes `--no-default-features` +# so an APK carries the 1.9 MB fixture only when it asked for `bench`. +fixture = ["screens"] +# The two Android widget trees, on the same axis: a build picks one. +transcript-screen = ["screens"] +tabs-screen = ["screens", "dep:tabs-ui"] +# P0's iris half (docs/RUST.md): the fixture screen with a "Run benchmark" +# control, driving the same scroll loop and streaming phase the Compose +# bench build type does. +bench = ["transcript-screen", "fixture", "dep:libc", "dep:tokio"] +# The JNI bridge `app/shellApp` calls -- notifications, the share target +# and the Keystore-sealed settings. +shell = ["dep:jni"] +# See `iris/Cargo.toml`'s feature of the same name. Never for a phone. +force-gles = ["screens", "iris/force-gles"] + +[dev-dependencies] +tempfile = "3" +tokio = { version = "1.53.1", features = ["rt", "time"] } + +# The Android builds, kept off `release`/`dev` so a desktop build is not +# also optimised for size and unwinding is not also turned off for the +# tests. `build-apk.sh` passes `--profile android-release`. +[profile.android-release] +inherits = "release" +panic = "abort" +strip = true +lto = "fat" +codegen-units = 1 +opt-level = "s" + +[profile.android-dev] +inherits = "dev" +panic = "abort" + +# Same reasoning as `iris/Cargo.toml`'s copy: full DWARF in every test +# binary is what made `cargo test` here write tens of gigabytes. +[profile.dev] +debug = "line-tables-only" + +[profile.test] +debug = "line-tables-only" + +# The headless harness tests (`iris::harness`, no window and no GPU) all +# open the bench fixture, so they say so rather than failing to compile +# when it is off. +[[test]] +name = "catch_a_fling" +required-features = ["fixture"] + +[[test]] +name = "fence_fling" +required-features = ["fixture"] + +[[test]] +name = "gesture_cancel" +required-features = ["fixture"] + +[[test]] +name = "input_log_roundtrip" +required-features = ["fixture"] + +[[test]] +name = "phone_screen" +required-features = ["fixture"] + +[[test]] +name = "top_edge" +required-features = ["fixture"] + diff --git a/iris/android-app/app/build.gradle b/app-rust/android-project/app/build.gradle similarity index 100% rename from iris/android-app/app/build.gradle rename to app-rust/android-project/app/build.gradle diff --git a/iris/android-app/app/src/main/AndroidManifest.xml b/app-rust/android-project/app/src/main/AndroidManifest.xml similarity index 99% rename from iris/android-app/app/src/main/AndroidManifest.xml rename to app-rust/android-project/app/src/main/AndroidManifest.xml index e950e43..833f9f0 100644 --- a/iris/android-app/app/src/main/AndroidManifest.xml +++ b/app-rust/android-project/app/src/main/AndroidManifest.xml @@ -39,7 +39,7 @@ - +