WIP: issue/slag-extraction #99
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
puregarlic/microclimate!99
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue/slag-extraction"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Scheme UI framework is now a tangled repo, this updates microclimate to rely on it
Replace the LiveKit/WebRTC media stack with Media-over-QUIC (moq) over an iroh transport, with our server acting as the relay. Server (server/): - Embed moq-relay (Cluster + Connection + Auth) on an iroh endpoint as a new services::relay module; single-node today, cluster-ready for the future. - Mint per-channel moq-tokens (HS256) the relay verifies; track live presence from origin announcements. - GetChannelToken now returns {relay_addr, moq_token, broadcast_path}; GetVoiceChannels reports participants from relay presence. - Drop livekit-api and the LIVEKIT_* env; add MOQ_* config. Client (src-tauri/): - Rewrite channels::manager to dial the relay over iroh H3/WebTransport, publish the mic as an Opus broadcast via moq-audio, and discover/decode peers via origin announcements into the existing cpal+sonora pipeline. - Derive active-speakers from RMS; emit room stats from the QUIC connection. - Same Tauri command/event names, so the frontend is unchanged. Drop livekit. Infra: - proto/channels.proto: new token response shape. - Dockerfile: Rust 1.96 (moq needs 1.95+) plus cmake/clang for aws-lc-sys. - Vendor upstream source as pinned git submodules under vendor/ (moq, iroh) for in-tree reference; exclude vendor/ from deno fmt/lint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>All seven components, eight shared libs, and four fixtures now exist as .scm alongside their .rhai originals, and every screen renders identically: a pixel diff of all ten screenshot scenarios shows no content differences. The Scheme versions are markedly shorter than what they replace, because the prelude absorbs the patterns Rhai needed by hand. Dropping falsy children turns the `if cond { x = x.child(...) }` rebuild dance into an inline (and cond ...), splicing list children turns array-building into (map ...), and lambdas closing over their environment retire the Fn("name").curry(id) contortion that existed only because Rhai handlers could not capture. Two harness improvements came out of the comparison: * settings_development was the only scenario running without a fixture, so it resolved the signed-in profile over the network and whether the user card had arrived by capture time was a coin flip - the screen genuinely differed between runs of the *same* runtime. It now uses the demo fixture like every other settings screen, and the two runtimes match exactly. * The modals fixture was stale: it seeded bare strings for the device lists, but settings_audio was updated to expect {id, name} records, so that screen would have failed on the Rhai side too. The Scheme port seeds proper records. A new test loads every shipped component and asserts that each entry point it defines actually resolves under its module prefix. An init that silently fails to resolve looks fine on screen but never fetches anything, which is the kind of failure that otherwise only shows up as a mysteriously empty sidebar. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>Second decoupling step: SchemeComponent no longer subscribes to any backend bus. The nine subscriptions (mute, active speakers, room stats, audio alerts, channel exited, reconnect status, audio-test, sidebar collapse, connection quality) were gpui tasks inside the component entity; they are now plain tokio watcher tasks in a new app-side watchers module, each following the same shape - read the bus, send a closure effect that lands the value in state, wait for a change - and exiting when the component is gone (send fails). The reconnect driver moves there too, spawned from the app rather than smuggled into the component constructor behind a name == "home" check. The component's side of the contract is one new type: ScreenServices { name, effects }, handed out by services(), which is None under a fixture so canned state is never clobbered by live buses. This is the seam the future slag builder's per-screen mount hook will formalize; for now lib.rs attaches watchers right after constructing each screen. Verified: 160 workspace tests; all 12 screenshot scenarios within 0.018% of baseline; live smoke with MC_AUTOJOIN=1 against jazz.gloom.garden - joined the first channel and presence-polled 20 times in 25s through the new watcher -> effect path, no errors. The reconnect ladder itself was not exercised (needs a killable connection); the driver moved verbatim and its status bus is covered by the reconnecting watcher. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>Third decoupling step, and the widest cut: scheme/host.rs no longer knows AppCore. What remains there is the framework surface - component state, the thread-local context registry, the SteelVal coercion helpers, and register_builtins() with the six state/navigation functions. HostCtx's app coupling is now a type-erased Rc<dyn Any> slot reached through with_app::<T>(), because the registry lives in thread-local statics and those cannot be generic over an app type. Everything else - the 41 app host functions (auth, channels, devices, users, profiles, mute, PTT, processing, server info, actor search) plus their support code (capture watchdog, presence poller, device swaps, profile/actor lookups) - moves to a new crates/ui/src/host.rs, which builds the `microclimate/host` module packs require: framework builtins first, then its own registrations against a per-component McHost { core, requested_profiles }. ScriptRuntime::new now takes the host module from the caller instead of building it, so the runtime never names an app capability either. Verified: 160 workspace tests; all 12 screenshot scenarios within 0.018% of baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>Fifth decoupling step: the last app knowledge leaves scheme/ behind three injection points, gathered in a new UiConfig the app builds once at startup. * Icons: materialize's make_icon now consults an app-supplied resolver before the built-in gpui-component names, and an unknown name renders a visible triangle-alert marker instead of silently borrowing the volume glyph. The 8-entry AppIcon table moves into icons::resolver(). * Bundled packs: PackLoader takes a Bundled { components, libs } from the caller instead of include_str!-ing four directories up into the app repo, which a separate framework crate could never do. The tables live in a new app-side packs module; shipped_components() becomes component_names() derived from the same data. * Env prefix: MC_PACK_DIR and MC_UI_FIXTURE become <PREFIX>_PACK_DIR and <PREFIX>_UI_FIXTURE with the prefix from UiConfig, so the screenshot harness keeps working under "MC" unchanged. MC_UI_DEMO and MC_FORCE_CONNECT were already read app-side. Verified: ui tests pass; all 12 scenarios within 0.018% of baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>7419343a458dbdf7fe4aView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.