Files
lumbridge-code/spikes
Metal AgentandClaude Opus 5 316fa32745 Graduate the shell out of spikes/ into apps/lumbridge
The product was spikes/gpui-shell: a cargo workspace of its own, named in the
root manifest's exclude list. It inherited neither unsafe_code = "forbid" nor
clippy pedantic, and ./scripts/ci.sh never compiled it. Every test written into
it silently never ran, and apps/lumbridge was an eleven-line stub printing a
version string.

Four separate research passes over the sidebar, settings, devices, and theme
work independently discovered they were about to write substantial new code into
that directory. Graduating first means writing it once.

- apps/lumbridge is the product; spikes/ui-shell-model becomes
  crates/lumbridge-ui-fixture and joins the workspace.
- scripts/ci.sh takes --headless and --ui. The headless pass excludes the two UI
  crates by name, so a contributor changing lumbridge-core does not wait on a
  window toolkit, and a runner that cannot carry GPUI still gates everything
  else. A new crate is headless by default rather than silently joining the slow
  job.
- scripts/native-libs.sh replaces the ad-hoc symlink in the launcher, and says
  which apt package actually fixes the problem instead of working around it
  silently. The stale libxcb/libxkbcommon symlinks in the old spike target
  directory are gone; only libxkbcommon-x11.so was ever needed.
- deny.toml and cargo deny check licenses. spikes/README.md called GPUI's
  licence closure a hard gate and the scorecard scored it pending; graduation
  makes it the product's closure, so it is enforced rather than described. Two
  rejections were reviewed and allowed with the reasoning recorded in the file:
  webpki-roots under CDLA-Permissive-2.0 (Mozilla's CA store, data not code,
  reached through ureq) and libfuzzer-sys under NCSA (reached only under
  all-features via gpui's image decoder; no shipped build links it).

Clippy pedantic across both crates is clean at -D warnings. render was 353
lines; render_sidebar, render_tabs, and render_root come out of it, which the
sidebar rework needed anyway. The remaining over-length functions are single
declarative element trees and carry per-function allows with reasons, not a
blanket suppression.

Decision 0017 records the two calls this forces: published gpui 0.2.2 behind an
accessibility adapter rather than an unpinned Zed revision and an MSRV bump, and
Floem frozen rather than maintained in parity or deleted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 23:05:12 -07:00
..

Native UI spikes

These disposable applications render the same fixture through GPUI and Floem. They are a decision instrument, not product code. The root workspace excludes this nested workspace so normal Lumbridge CI does not download or compile both UI frameworks.

The GPUI spike uses published gpui 0.2.2. The Floem spike pins upstream commit 778bb5f2aa08429e579ee2e6ac97e84fbf18b618; the crates.io floem 0.2.0 package lags the current API substantially enough that comparing it to current GPUI would not be representative.

Both spikes must preserve the same information architecture:

  • workspace/sidebar and remote host state;
  • two rows of three busy surfaces;
  • local and remote terminal/agent panes;
  • native Markdown editor/preview and browser placeholders;
  • connection, harness, usage, and burn context in the footer.

GPUI also has an integration mode with one real local PTY owned by lumbridge-runtime; the other five surfaces remain deterministic. Floem and the shared model retain the all-deterministic mode for like-for-like framework comparison. GPUI feeds raw output through lumbridge-terminal and sends encoded keyboard input and terminal protocol replies through the bounded runtime actor. Its visual adapter coalesces VT cells into native styled runs, paints cursor shapes, and resizes the engine and PTY from the middle 60% of a responsive one/three/five-panel workspace. Every panel owns separate context and decision regions. Retained-history navigation is wired; text selection and mouse input remain intentionally unfinished.

Build independently:

cargo build --release --manifest-path spikes/gpui-shell/Cargo.toml
cargo build --release --manifest-path spikes/floem-shell/Cargo.toml

Each candidate is an independent Cargo workspace. GPUI pins taffy 0.9.0 while current Floem requires taffy 0.9.2; putting them in one comparison workspace creates an artificial resolver conflict and would let one candidate's dependency decisions distort the other candidate's build.

The comparison records release build time, binary size, startup, idle RSS, six-pane streaming frame time, key-to-present latency, accessibility/IME, window behavior, browser-child integration, packaging, dependency count, and license closure on macOS, Ubuntu, and Omarchy. A build is not adoption: GPUI's complete dependency-license closure remains a hard gate.