Skip to content

feat(android): AffineScript UI in the Gossamer webview (#83 sub-PR #8)#127

Open
hyperpolymath wants to merge 2 commits into
mainfrom
chore/gossamer-ui
Open

feat(android): AffineScript UI in the Gossamer webview (#83 sub-PR #8)#127
hyperpolymath wants to merge 2 commits into
mainfrom
chore/gossamer-ui

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Sub-PR #8 — AffineScript UI in the Gossamer webview

Part of the Android Kotlin→Rust/Gossamer migration (epic #83, RFC PR #97, sub-issue #114).

Reimplements the UI currently in android/app/src/main/java/ai/neurophone/MainActivity.kt + res/layout/activity_main.xml as the AffineScript webview UI that the Gossamer Android shell loads. The Kotlin sources are left in place; their removal happens at migration cutover.

Dependency note

Needs #3 (Gossamer scaffolding / webview host) and #4 (NativeLib→Rust JNI) — both in parallel and not merged. Based off main; their structure is assumed and every assumption is marked TODO(#83 rebase) / TODO(#83).

Files added

All new files carry SPDX-License-Identifier: MPL-2.0. Under android/app/src/main/assets/gossamer-ui/:

File Purpose
src/bridge.affine Typed bridge to the native Rust core (was NativeLib JNI): init, start, stop, process_sensor, query, query_local, query_claude, get_neural_context, get_state, reset, is_running. Config ported verbatim from MainActivity.createConfig().
src/ui.affine View/controller logic ported 1:1 from MainActivity: init-on-load, Start/Stop toggle, 500 ms neural-context poll, query + "Prefer Local" routing.
index.html Webview entry; element ids match ui.affine queries.
styles.css Visual parity with activity_main.xml (16dp padding, centred header, monospace neural-context panel, spinner, etc.).
deno.json Deno build/check/fmt tasks (no npm/Node).
build.sh AffineScript → Deno-ESM build wiring.
dist/ui.mjs Committed compiler-output stub (see below).
README.adoc Documents bridge assumptions + TODOs.

Plus a scoped .gitignore negation so the committed dist/ui.mjs stub is tracked while the general dist/ ignore stays.

AffineScript build wiring + assumptions

  • AffineScript (.affine) compiles to Deno-ESM via the estate affinescript toolchain (OCaml/Dune CLI: check / fmt / compile --target deno-esm), driven through Deno tasks: deno task check:ui / build:ui / fmt:ui. build.sh is the single CI-ready entry point.
  • The affinescript compiler is not yet vendored in this repo/CI. So dist/ui.mjs is a hand-written generated-output stub faithfully mirroring src/ui.affine + src/bridge.affine, keeping the webview loadable/reviewable today. build.sh falls back to the committed stub when the compiler is absent (and says so loudly). TODO(#83): vendor/pin the toolchain, flip USE_STUB=0, regenerate, delete the stub, wire deno task build:ui into CI.
  • Bridge contract assumed (owned by chore(deps): update rand_distr requirement from 0.4 to 0.5 #3/chore(deps): update thiserror requirement from 1.0 to 2.0 #4): Gossamer injects globalThis.gossamer with invoke(cmd, args): Promise<string>; command names are snake_case forms of the old NativeLib methods; host serves index.html as the webview root. All marked TODO(#83 rebase).
  • Sensor acquisition intentionally not in this UI — the foreground Rust service (chore(deps): update thiserror requirement from 1.0 to 2.0 #4) registers sensors natively; bridge.process_sensor stays exposed for parity.

Verification

  • build.sh runs clean with the stub fallback (exit 0).
  • All 8 new files carry the MPL-2.0 SPDX header; deno.json is valid JSON.
  • Cargo workspace: no Rust/Cargo files touched (web assets + .gitignore only). cargo build --workspace currently fails on main in the lsm/esn crates due to a pre-existing rand 0.10 API drift (.random()/.sample()), present on origin/main before this branch and unaffected by these changes.

TODOs / risks

Language policy

AffineScript (primary app language) + HTML/CSS + a Deno-run Bash build script. No TypeScript, Node, or npm. The single .mjs is a compiler-output stub, not hand-authored application logic.

https://claude.ai/code/session_01Gu1JFCZHuBtBhAWPr4sMQw


Generated by Claude Code

Reimplement the Kotlin MainActivity + activity_main.xml UI as the
AffineScript webview UI loaded by the Gossamer Android shell.

- src/bridge.affine: typed bridge to the native Rust core (was NativeLib
  JNI): init/start/stop/process_sensor/query/query_local/query_claude/
  get_neural_context/get_state/reset/is_running.
- src/ui.affine: view/controller logic ported 1:1 from MainActivity
  (init, start/stop toggle, 500ms neural-context poll, query + Prefer
  Local routing).
- index.html + styles.css: webview entry with visual parity to the old
  Android layout.
- deno.json + build.sh: AffineScript -> Deno-ESM build wiring (no
  npm/Node). build.sh falls back to a committed compiler-output stub
  (dist/ui.mjs) until the affinescript toolchain is vendored.
- README.adoc: documents bridge assumptions and TODO(#83) markers.

Depends on #3 (Gossamer host) and #4 (NativeLib->Rust JNI), both in
parallel and not merged; assumptions marked TODO(#83 rebase).

No Rust/Cargo files touched; web assets only.

https://claude.ai/code/session_01Gu1JFCZHuBtBhAWPr4sMQw
@hyperpolymath hyperpolymath marked this pull request as ready for review June 3, 2026 21:08
@hyperpolymath hyperpolymath enabled auto-merge (squash) June 3, 2026 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants