Mobile (iOS/Android): rebase onto 0.2.19 and bring the client to the current model#133
Merged
Merged
Conversation
…plan
Add `allmystuff-mobile-core`, the pure, transport-agnostic foundation of the
AllMyStuff phone app, plus `docs/MOBILE.md` — the full architecture and
roadmap for shipping AllMyStuff to iOS and Android.
The phone joins the mesh as a true peer by embedding `myownmesh-core`
in-process: the desktop's spawn-a-daemon model can't cross to iOS, which
forbids child processes, so on mobile the phone *is* the node. A cross-compile
probe confirms the crux — the entire `myownmesh-core` Rust tree type-checks for
`aarch64-linux-android`; only the NDK toolchain is missing, no portability
blocker.
allmystuff-mobile-core (pure serde, `unsafe = forbid`, 35 tests):
- caps: the phone's viewer/controller Capability set (+ opt-in host
scope), including the synthetic `display-in` sink a remote desktop
must land on (Display media, not Video)
- node: assemble the phone's NodeProfile for presence
- connect: build RouteControl::Offer for screen/camera/audio
(catalog-validated) and terminal/files (synthetic `generic`
routes), byte-identical to `amst` and the desktop GUI
- transport: the MeshClient seam + classify(channel, payload) -> typed Inbound
- media: client pipelines — MJPEG reassembly + a native-decode seam
(video), normalized touch/keys (input), terminal, and a
request/reply file client with Read-chunk reassembly
Reuses allmystuff-graph/protocol/session as-is; the node/ engine and the
updater stay desktop-only. The `myownmesh-ffi` binding and the Tauri-mobile
shell are specified in docs/MOBILE.md §5/§8 as the next Phase-0 steps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017jhWY2rKdxttnAAhWaVjMe
…op UI allmystuff-mobile-core shipped the phone's brain but nothing that runs on a phone. This adds the Tauri 2 mobile shell that turns it into an app. - gui/mobile: a standalone Tauri crate that reuses the desktop Svelte UI verbatim (frontendDist = ../dist) and backs it with the viewer/controller core instead of spawning a desktop node — iOS forbids the child process the desktop model needs, so the engine embeds in-process behind mobile-core's MeshClient seam (the next slice). - scan_self is real: it puts a phone node with the real viewer/controller capability set on the graph via mobile_profile(). Calls that need a live mesh stay unregistered so the frontend keeps its demo behaviour until the embedded engine lands, rather than this side faking a mesh. - Its own Cargo workspace, so the desktop build is untouched and CI stays green. - CI: a gui-mobile job type-checks the backend for aarch64-linux-android on every push — no NDK needed, since the shell links no C-building crate yet. - docs/MOBILE.md: shell marked in-repo; exact `tauri android/ios` build commands. Verified: `cargo check --target aarch64-linux-android` passes and the shared frontend builds and embeds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017jhWY2rKdxttnAAhWaVjMe
The mobile client core was written against the June-25 model; main has since moved nine releases (fleets, KVM appliances, the presence clock-skew sample). Bring the rebased core current so it type-checks and stays clippy-clean: - node: fill the four NodeProfile fields that landed since — fleet_name / fleet_owner (empty until the phone is adopted into a fleet, then handed down like any desktop member), kvm: None (a phone is a viewer/controller, never a KVM appliance), and sent_at: 0 (stamped per send by the presence path, as the desktop does — this crate has no clock). - transport: box Inbound::Presence(NodeProfile); the profile grew enough that it now dominates the enum size (clippy::large_enum_variant). cargo test -p allmystuff-mobile-core → 35 + 1 doctest green; clippy clean; cargo check --workspace clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JmoJ9sRbE1wS99bXGWHHVY
…2.19 model The rebased core compiled against current, but it only spoke the June-25 subset of the control channel — route offers, terminal, files. Add `control.rs`, the rest of the surface a viewer/controller phone drives on peers it co-owns, every builder matched byte-for-byte to `amst`/the GUI (the tests pin the `t`/`kind` tags and fields, so a drift from the daemon contract fails `cargo test`): - fleet-machine admin (AppControl): upgrade / restart the app / reboot the device — "reboot the wedged server from your phone", gated owner/fleet like the desktop. - KVM curation (KvmControl): attach / detach / mesh add/remove, plus the recognition helpers `is_kvm` and `kvm_web_site` (named-id-then-first-web, the desktop's resolution order) a phone needs to render the KVM drawer. - per-route video negotiation the viewer drives (RouteControl): `tune` (cap resolution/bitrate/fps — the lever a phone on cellular leans on hardest), `refresh_video` (force a clean decode entry), `video_feedback` (report decode health upstream). - the shared-shell picker (`list_terminal_sessions` → TerminalSessionsRequest), pairing with connect.rs's existing tmux-style `attach` argument. - fleet-site management (SiteControl list / set-exposed) and a per-node presence refresh (ProfileRequest). Anything the host sends back — a Tune echo, a TerminalSessions answer, a VideoLane binding — already arrives typed through transport::classify, so this is purely the outbound half. Also refresh docs/MOBILE.md: the core is tracked to the 0.2.19 model, control.rs is in the tree, and the quality-adaptation and Phase-0 notes reflect what landed. Scope held deliberately to viewer/controller: device *adoption* (claim codes + fleet-key handoff, which makes the phone a fleet owner) is a separate slice, noted for follow-up rather than half-built here. cargo test -p allmystuff-mobile-core → 43 + 1 doctest; clippy -D warnings clean; cargo fmt --check clean; cargo build/test --workspace green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JmoJ9sRbE1wS99bXGWHHVY
A model-drift audit of the rebased core against 0.2.19 found three real holes in the viewer/controller surface. Fix them: - connect: add `offer_input` — the outbound half of remote control (the phone's `keyboard-mouse` Input source → the remote's `:control` Input sink), catalog-validated exactly like the media routes. Every existing helper put the phone on the *sink* side (it could watch a screen but had no authorized way to *drive* it, even though `InputEncoder` already produces the events). - transport: `answer_profile_request` + document the inbound obligation on `Inbound::Control` — a viewer MUST re-advertise on `ControlMessage::ProfileRequest` (the round-trip behind a peer's pull-to-refresh) or it ages out of that peer's graph. Generic over the `MeshClient` seam (which isn't dyn-compatible). - lib: surface the full landed control/connect surface at the crate root and in the prelude — the previous commit exported only part of `control.rs` (`kvm_mesh_add/remove`, `profile_request`, `site_list/set_exposed` were defined and tested but not public), plus `offer_audio/camera/input/teardown` and `mobile_features`. Larger gaps the audit flagged (inbound H.264 lane-receive with VideoLane→route mapping, clipboard/audio/site planes, device adoption, fleet governance) are tracked for follow-up slices, not force-fit here. cargo test -p allmystuff-mobile-core → 46 + 1 doctest; clippy -D warnings clean; fmt clean; build --workspace green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JmoJ9sRbE1wS99bXGWHHVY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refreshes the mobile app work from #101 (
claude/gifted-knuth-twlult), which had gone ~9 releases stale (based onmain@fa183d7, June 25). This branch replants those two commits onto today'smain(0.2.19) and updates the client to the current AllMyStuff model. It supersedes #101 — once this looks right, #101 can be closed.What's here
Four commits, on top of current
main:feat(mobile): land the mobile client core …— the originalallmystuff-mobile-core(unchanged, cherry-picked).feat(mobile): add runnable Tauri shell (gui/mobile) …— the original shell (unchanged, cherry-picked).fix(mobile): compile the rebased core against the current 0.2.19 model— the core was written against the June-25 model;mainhas since added fleets, KVM appliances, and the presence clock-skew sample. Fixes:NodeProfilegainedfleet_name/fleet_owner/kvm/sent_at— filled for a phone (empty fleet until adopted,kvm: None,sent_atstamped by the presence path like the desktop).Inbound::Presenceboxed — the profile grew enough to tripclippy::large_enum_variant.feat(mobile): bring the phone's control surface to parity with the 0.2.19 model— addscontrol.rs, the rest of the control channel a viewer/controller phone drives, every builder matched byte-for-byte toamst/the GUI (tests pin thet/kindtags so a drift from the daemon contract failscargo test):AppControl): upgrade / restart-app / reboot-device — "reboot the wedged server from your phone".KvmControl): attach / detach / mesh add-remove, plusis_kvm+kvm_web_siterecognition helpers for the KVM drawer.RouteControl):tune(cap resolution/bitrate/fps — the lever a phone on cellular leans on hardest),refresh_video,video_feedback.list_terminal_sessions→TerminalSessionsRequest), pairing withconnect.rs's existing tmux-styleattach.SiteControl) and a per-node presence refresh (ProfileRequest).Inbound host replies (a
Tuneecho, aTerminalSessionsanswer, aVideoLanebinding) already arrive typed throughtransport::classify, so this is purely the outbound half.docs/MOBILE.mdis refreshed to match.Conflicts resolved in the rebase
Cargo.toml— mobile-core dep pinned at0.2.19(was0.2.4).README.md— the Mobile row kept; the obsolete "File/disk streaming 🚧" row dropped (main already reconciled it into "File access ✅")..github/workflows/ci.yml— thegui-mobileandroid job applied cleanly.Verification
cargo test -p allmystuff-mobile-core→ 43 unit + 1 doctest, all green (35 → 43 with the new control tests).cargo clippy -p allmystuff-mobile-core --all-targets -- -D warnings→ clean.cargo fmt --check→ clean.cargo build --workspace/cargo test --workspace→ green.gui/mobileshell is unchanged and consumes only additive names from the prelude; its android CI job continues to cover it.Scope held deliberately
This is viewer/controller parity, not a rewrite (the core was sound and tested). Device adoption from the phone (claim codes + fleet-key handoff, which makes the phone a fleet owner) is a separate, clearly-scoped slice — noted for follow-up rather than half-built here. Genuine "ship" still depends on the external work called out in
docs/MOBILE.md §5/§8: themyownmesh-ffiengine embedding, the native H.264 decode bridge, and a macOS/Xcode + Android NDK build/signing host.🤖 Generated with Claude Code
https://claude.ai/code/session_01JmoJ9sRbE1wS99bXGWHHVY
Generated by Claude Code