Use the v1.16.1 platform entry point, AlertDialog, and ID-based Sidebar constructor while preserving the gallery text, menu order, and 180px sidebar width.
A rustfmt run was cut short by a full D: drive and left
gpui_shell/terminal/view.rs at 0 bytes. Restored from the editor
history snapshot taken at 18:32 - the selection auto-scroll work and
the suggest_env wiring are both back in.
Emergency baseline snapshot, committed with --no-verify: the tree does
not compile yet (missing SuggestEnv import, one stale
update_selection_scroll call site) and the pre-commit size budgets are
pre-existing failures on this branch.
Physically relocates the validated GPUI surface out of the lab crate into nebula_app/src/gpui_shell/ (git mv keeps history): the terminal stack (view/element/session/keymap/mouse_protocol/colors), the config bridge (nebula.toml + nebula_settings.txt + theme tables), the workspace view and the theme/prelude glue. Per product ruling, nebula_gpui is a scratch lab - it keeps only the component gallery (terminal preview removed) plus annotated copies of theme/prelude, and its Cargo manifest drops the terminal/settings dependencies. The gpui-shell feature is now self-contained: nebula depends directly on gpui/gpui-component/-assets (redirected to our fork by the root patch table), nebula-settings and futures; the nebula-gpui crate dependency is gone. Entry points: 'nebula --gpui' runs the GPUI main-window form on the main thread with winit never starting (P3 acceptance form; gates get re-measured here), and the NEBULA_GPUI_SHELL=1 dedicated-thread spike stays until the P3 takeover completes. Verified: cargo check on both crates, and nebula --gpui opens the Nebula main window with working tabs, ConPTY terminal, CJK text and powerline prompt (screenshot .tmp_parity_gpui-in-nebula.png).
Mouse-mode apps (vim/htop) now own the pointer: press/release/drag/motion/wheel are encoded per protocol (SGR, normal, UTF-8 extension) and reported to the app, with Shift as the local-selection escape hatch - same as the legacy shell. The encoder is a pure module ported verbatim from input/mouse.rs with unit tests locking the byte sequences. Right-click follows the legacy Windows convention (copy+clear when a selection exists, paste otherwise), copy_on_select fires on release, Shift+click extends an existing selection, and Shift+PageUp/PageDown/Home/End page the scrollback on the primary screen.
New zero-dependency workspace crate owning nebula_settings.txt path resolution, key semantics and the per-theme terminal color tables (background, light-theme foreground/ANSI-16 replacement, powerline slots 16..=23) - values transcribed verbatim from the legacy shell's theme.rs, which stays frozen per P4. The GPUI lab now honors the user's actual runtime intent: theme (SilverLight etc.) applied over toml colors in the same order as apply_term_colors, font family/size from the settings UI, default cursor shape/blink wired into the engine Term config, copy_on_select exposed for the next slice. Cargo.lock intentionally not committed: it currently carries the user's in-flight gpui-fork switch.
Port nebula_app's builtin_font coverage (box drawing, block elements, legacy sextants/blocks, Powerline separators) from pixel rasterization to renderer-agnostic fill primitives: axis-aligned rects plus convex polygons, snapped to device pixels so strokes stay crisp and join seamlessly across cells. RenderSnapshot::capture now routes these cells to box_glyphs instead of text segments - the typography engine never touches them, which roots out the box-line misalignment CJK fonts cause. The GPUI element consumes the primitives via paint_quad/paint_path (cursor inversion rules unchanged). Known deltas vs the legacy rasterizer: narrow-cell Powerline tips clip instead of falling back to the font, and shade blocks use alpha 64/128/192. Engine tests: 202 passing (11 new).
nebula_gpui now exposes run_shell() as a library entry so nebula.exe can
host the GPUI UI layer on a dedicated thread (route C: one program, GPUI
provides the component layer). The standalone bin remains for development.
Off by default; enabled via the gpui-shell feature + NEBULA_GPUI_SHELL=1.
Layering: Term (model) -> render contract -> frontend backend.
- CellMetrics + TerminalViewport: floor division, minimum grid, exact
text-area pixels (cols x cell_width) for PTY/app reporting.
- ViewportTracker: resize coalescing, monotonic revisions (a stale resize
can never override a newer one), and pixel-only changes still reported
to the PTY even when rows/cols are unchanged.
- RenderSnapshot: single-lock plain-data capture (bg runs, selection runs,
wide-aware text segments, cursor, OSC color-override copy). Colors stay
as vte values; frontends resolve them outside the lock.
- gpui element/view now consume the contract: grid math single-sourced in
the tracker, cursor-cell isolation for block-cursor inversion. Swapping
the paint backend later touches element.rs only.
- 6 contract tests (segmentation, cursor isolation, viewport rules).
TerminalView now emits TitleChanged/Exited and owns session teardown
(Msg::Shutdown on removal, Drop as backstop). TerminalPanel adapts the
terminal to the dock Panel contract with a title_suffix close button,
since a root-level TabPanel never renders its own. NebulaWorkspace
wires TitleBar + tabs with ctrl-shift-t/w hotkeys (passed through the
terminal key handler), closes tabs on shell exit, and quits when the
last tab closes. The component gallery moves to a secondary window.
ConPTY + EventLoop wired through a futures channel into a GPUI entity;
custom Element paints the grid from a single-lock snapshot (bg runs,
force_width text segments for CJK alignment, cursor, selection); view
handles keyboard encoding, mouse selection, wheel scroll, clipboard,
and IME via EntityInputHandler. No fork of either side; boundary stays
symmetric (no GPUI types in nebula_terminal, no terminal types outside
src/terminal).