Build interactive native workspace vertical slice
CI / rust (push) Successful in 1m43s

This commit is contained in:
2026-08-31 16:15:32 -07:00
parent de89b015bc
commit 27beb69ff8
19 changed files with 10535 additions and 200 deletions
+13 -6
View File
@@ -41,13 +41,17 @@ messages should be real from the beginning.
- `lumbridge`: installable application entry point.
The scaffold currently contains `lumbridge-core`, `lumbridge-storage`,
`lumbridge-buzz`, and the entry point. Larger runtime crates are added after
their architecture spikes pass.
`lumbridge-buzz`, `lumbridge-pty`, and the entry point. Larger runtime crates are
added after their architecture spikes pass.
## Terminal path
The runtime owns PTYs, child process groups, resize signals, input ordering, and
raw output. The terminal engine turns output into immutable render snapshots and
raw output. The first `lumbridge-pty` boundary now uses `portable-pty` behind a
single-owner session, a fixed credential-free child environment, validated
sizes, an 8 KiB bounded output queue, resize/input/wait operations, and Unix
process-group cleanup. It deliberately does not emulate a terminal or persist
scrollback. The terminal engine turns output into immutable render snapshots and
bounded deltas for the UI. Scrollback is chunked and persisted separately from
the live screen to prevent large agent transcripts from blocking input.
@@ -59,15 +63,18 @@ and simultaneous automation plus human input.
## UI decision gate
Do not lock the project to a webview or to Zed's private implementation details
before a measured spike. Compare:
Do not lock the project to a webview or to Zed's application implementation
details. The measured spike compares:
1. GPUI for a Zed-like native model and excellent text-heavy interaction.
2. Floem for an independent native Rust model with existing editor primitives.
The winner must render six busy panes smoothly, keep input latency low, support
IME/accessibility, package on macOS and both Linux targets, and avoid a license
or upstream-stability trap.
or upstream-stability trap. Current Zed GPUI is the provisional winner because
its AccessKit semantics compile while the pinned Floem revision has no semantic
accessibility integration. This remains behind a narrow adapter until platform
assistive-technology, IME, packaging, licensing, and release measurements pass.
## Local-first and remote session path
+13
View File
@@ -101,6 +101,19 @@ cargo xtest
2025. `scripts/watch.sh` uses Bacon and retains a cargo-watch fallback for people
who already have the final cargo-watch release installed.
## Implemented vertical-slice coverage
- The framework-neutral six-surface model has deterministic tests for focus,
direct selection, needs-input transitions, command-palette lifecycle,
identical GPUI/Floem action replay, bounded output, and workload counters.
- `lumbridge-pty` runs synthetic `/bin/sh` tests for raw output, non-zero exits,
input, resize, one-chunk backpressure, hung-process termination, invalid
dimensions, and exclusion of provider credentials from the child environment.
- The current-GPUI probe compile-checks real AccessKit element wiring and real
platform input-handler installation. Unit tests cover its semantic tree and
UTF-16/UTF-8 composed-text mutations. OS screen readers, IME candidate windows,
and macOS behavior remain platform tests.
## CI matrix as the project grows
Every change runs format, Clippy, unit, contract, integration, and doctests on
+7
View File
@@ -10,6 +10,13 @@ This decision stays open until the finalists run the same workload. Choosing on
repository popularity or a polished demo would hide the risks that matter for a
terminal-heavy, accessibility-aware, cross-platform IDE.
The current vertical-slice result is GPUI-first, not GPUI-final: current Zed
GPUI compile-proves the required AccessKit and IME handler paths, while the
pinned Floem revision fails the semantic-accessibility hard gate. The app-facing
UI boundary must stay narrow until platform AT/IME, packaging, license closure,
and release measurements finish. See `UI_SPIKE_SCORECARD.md` for evidence and
remaining gates.
## Finalists
### GPUI
+49 -3
View File
@@ -10,8 +10,8 @@ from macOS and Linux and the hard gates pass.
| Builds on Ubuntu | yes | conditional | pass |
| Builds on Omarchy/Arch | yes | pending | pending |
| Dependency/license closure permits Apache-2.0 distribution | yes | pending | pending |
| Keyboard navigation + AccessKit tree | yes | pending | pending |
| IME and composed Unicode input | yes | pending | pending |
| Keyboard navigation + AccessKit tree | yes | keyboard pass; current-GPUI semantics compile; platform AT pending | fail: no AccessKit integration at pinned revision |
| IME and composed Unicode input | yes | framework API exists; end-to-end pending | editor API exists; end-to-end pending |
| Isolated system browser child | yes | pending | pending |
| Cold startup, p50/p95 | record | pending | pending |
| Idle RSS / six-stream RSS | record | pending | pending |
@@ -43,4 +43,50 @@ performance numbers. GPUI's Ubuntu row remains conditional because the host has
the runtime `libxkbcommon-x11.so.0` but lacks the unversioned development linker
name normally supplied by `libxkbcommon-x11-dev`. Floem current main also
requires its `editor` feature for the style/label modules used by this shell;
that feature is now explicit in the spike. Neither finding decides the UI stack.
that feature is now explicit in the spike. Neither build result by itself
decides the UI stack.
## Accessibility gate and provisional direction
The published `gpui 0.2.2` used by the visual shell has focus and keyboard
actions but does not expose the current AccessKit element API. An isolated probe
therefore pins GPUI directly to Zed commit
`ce48461eaadd16c65c31f835511ab96bd3b6e746` with its matching Rust 1.97.1
toolchain. The real element wiring compiles with stable accessibility IDs,
workspace/pane/terminal roles, selected state, focus tracking, and a needs-input
description. The same probe installs real `EntityInputHandler` and
`ElementInputHandler` implementations and tests marked-text commit, a composed
accent, and a multi-codepoint emoji without splitting UTF-8. Three deterministic
tests pass. AT-SPI/OS IME on Linux and VoiceOver/IME on macOS remain end-to-end
gates.
The pinned Floem revision has keyboard focus and editor IME plumbing but no
AccessKit dependency or semantic tree. That fails Lumbridge's accessibility
gate without a maintained framework fork or adapter. The provisional direction
is therefore **GPUI-first using current Zed GPUI behind a narrow Lumbridge UI
adapter**. The published GPUI shell remains the lightweight interaction and
visual benchmark until the dependency/toolchain migration is accepted.
This is not the final cross-platform release decision. Current-GPUI validation
on amd-server required a 624 MiB Rust 1.97.1 toolchain, a 691-package lockfile,
and 4.4 GiB of debug artifacts across check, test, Clippy, and build. Packaging,
license closure, IME, platform assistive technology, browser parenting, macOS,
and Omarchy still have to pass.
The comparable Floem shell passes build, test, strict Clippy, live rendering,
streaming, mouse selection, and numeric pane selection on metal. Its command
palette opens through the visible clickable affordance and uses Floem's native
`TextInput`, but Ctrl/Cmd+K did not reach the handler in the X11 automation
probe. That unresolved focus/event-routing behavior is another current strike
against adopting Floem; it is recorded rather than hidden behind the clickable
fallback.
## Measurement semantics
Both renderers consume the same deterministic six-surface action stream. Each
tick invalidates six surfaces, appends one bounded line to each of the three
terminal fixtures, and records stable event/revision counters. The GPUI footer
currently reports dispatch-to-element-build p50/p95 over a bounded 256-sample
window. It is deliberately not called key-to-present or frame-present latency:
neither candidate exposes a reliable public cross-platform post-present
callback. True present latency requires an external platform probe.
+107
View File
@@ -0,0 +1,107 @@
# Decisive native workspace vertical slice
## Outcome
The slice must let an engineer notice one waiting agent, move focus to it from
the keyboard, inspect the request, and choose a safe next action without losing
the state of five other busy surfaces. It is a product interaction test and a
framework decision gate, not a decorative dashboard.
## Current-run audit
The 2026-08-31 GPUI baseline succeeds at calm density: the six surfaces are easy
to scan, typography is consistent, and local/remote targets remain visible. It
fails the task flow in four important ways:
1. all panes have equal visual priority, so `NEEDS INPUT` is too easy to miss;
2. no pane exposes visible keyboard focus or selection;
3. the command palette affordance has no interaction behind it;
4. status and usage text in the footer is too quiet to explain provenance or
confidence at a glance.
Screenshots for the audit are stored outside Git under
`~/shots/2026-08/lumbridge-ui-audit/`. Accessibility and IME correctness cannot
be established from screenshots and remain explicit runtime gates.
## Preserved design language
- Near-black blue surfaces with one cool-blue action accent.
- Thin borders and compact spacing; no elevated card shadows.
- Text carries most hierarchy. Color is supplementary and never the only state
signal.
- Monospace content inside terminal surfaces; system UI typography elsewhere.
- Dense information, but only the focused or waiting surface becomes prominent.
## Orca reference, translated for Lumbridge
The visual reference is the MIT-licensed Orca repository at researched commit
`02a7742406a5a84fb372d6255d5a4367421990bd`. Its screenshots are product
research, not source assets for Lumbridge. We adapt these interaction patterns:
- a worktree/task-first sidebar whose rows show state without becoming large
cards;
- a quiet top tab strip for mixed terminal, Markdown, browser, and review
surfaces;
- one primary work surface with optional splits, instead of forcing every
surface into an equal dashboard tile;
- narrow contextual tools, such as files, review, or Buzz, that can collapse
when the terminal needs the space;
- usage and agent state at the edge of the workspace rather than in modal
account pages.
Lumbridge deliberately differs where its product model differs: remote runtime
ownership is always visible, `needs input` receives a dedicated attention path,
usage includes provenance and uncertainty, and Buzz is a signed collaboration
surface rather than a hosted Lumbridge control plane.
## Visual hierarchy
1. The top bar names the current workspace, repository/branch, and command
palette shortcut.
2. The sidebar starts with a compact `ATTENTION` group, followed by workspaces
and remote hosts. It does not become a notification feed.
3. The active pane receives a two-pixel accent edge plus a quiet tinted header.
4. A waiting pane uses an amber semantic label and remains visible when another
pane is selected. The label always includes words such as `NEEDS INPUT`.
5. Pane headers expose title, execution target, harness state, and unread count
in a stable order.
6. The footer groups connection state, selected-harness identity, usage-window
provenance, and burn forecast into readable regions.
## Keyboard task flow
- Arrow keys or `h/j/k/l`: move focus through the 2×3 pane grid.
- `1` through `6`: focus a pane directly.
- `Cmd+K` on macOS or `Ctrl+K` on Linux: open the command palette.
- Typing while the palette is open changes its query; arrows change the result;
`Enter` runs it; `Escape` closes it and restores pane focus.
- `Enter` on a waiting agent opens its request detail. Approval remains a
separate explicit action and is never triggered by focusing the pane.
- `Escape` closes transient UI before it changes workspace state.
Every command is represented by the shared interaction model so GPUI and Floem
receive the same state transitions and tests.
## Decisive workload
- One deterministic tick invalidates all six surfaces and appends bounded output
to the three terminal panes. Framework adapters consume the same event trace.
- One pane enters and leaves `needs input` through a deterministic event.
- Markdown, browser-boundary, and review panes update counters without using a
web application shell.
- The model records actions, revisions, six-surface updates, and bounded terminal
line counts. Framework adapters label each measured timing stage explicitly;
element-build timing is never presented as display-present timing.
- A later PTY adapter replaces one synthetic stream without changing the UI
contract. Synthetic streams stay available for repeatable performance tests.
## Hard gates
- Every focus movement and palette command is unit tested without a window.
- Focus and `needs input` remain distinguishable in monochrome screenshots.
- The current-GPUI input probe preserves composed Unicode and multi-codepoint
graphemes. Real candidate-window placement still requires Linux/macOS testing.
- The accessibility tree names each pane, selected state, execution target, and
waiting state.
- Six streams remain responsive while the palette is open.
- Closing the UI never implies that a runtime-owned session has stopped.