aesel: an iPhone app whose renderer is SwiftUI and whose thinking is not master
apple/aesel is a SwiftUI application. Session.swift draws the six notification kinds AcServer already emits — the contract the desktop TUI reads — so the port is a renderer, not a rewrite. easel/src/ac-server.mjs and publish.mjs run unmodified in a WKWebView that is never shown. That hidden webview is the trade, and it is the opposite of Oskiewar's. Its Mac app hands JavaScriptCore a bundled script and drives Metal, because a webview cannot draw a game; main.swift:569 notes it gets no JIT for the trouble. Aesel renders text, and its piece preview must be a WKWebView on every platform anyway, so the thing Oskiewar avoids is something Aesel already needs. A second invisible one buys fetch, streaming getReader(), TextDecoder and ES modules — none of which JSC has, all of which the shared bridge is written against. session.mjs is the headless half both renderers share. app.mjs is not migrated onto it yet; another session is editing that file. Two failures found by running it rather than by reading it: didFinish is not readiness. It fires before the module script evaluates, so globalThis.aesel may not exist and restore() threw "Can't find variable: aesel". The page posts `ready` after installing the global; that is the signal now. publish.mjs sets User-Agent, which is right for Node and forbidden in a webview. Chrome drops it silently — the browser client publishes fine. WebKit leaks it into the CORS preflight, /presigned-upload-url allows only Content-Type, Authorization and X-Requested-With, and the refusal surfaces as "Load failed" with no hint which of three steps failed. session.mjs strips forbidden headers and names the step; publish.mjs keeps identifying itself on the desktop. Verified in the simulator: signed in, ran turns, wrote the piece, published it, and rendered it live in the stage. The model is the weak part — it wrote ink() without destructuring it, so paint threw after the wipe and the preview looked like a plausible solid colour, then rewrote the same broken piece twelve times because nothing reports runtime errors back. main's runtime-feedback.mjs and ac_preview close that loop; this branch's bridge has neither. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> (cherry picked from commit 23ca9b24153174c7e9b4d535e36683706479f54d)