Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Native result block presentation

## Status

Implemented locally. Native interaction and parser regressions pass. Desktop
visual acceptance and release/platform validation remain separate.

## Context

The approved terminal layout uses natural table columns, UI-font headings,
numbered code blocks and transient controls. Component defaults center button
labels, stretch Markdown tables and provide neither code line numbers nor the
required heading font. Replacing text with unselectable labels would lose
existing reading behavior.

## Evidence

The pinned component supports Markdown block extensions and selectable HTML/text
views. Its button activation requires both key down and key up; its mouse click
deliberately does not transfer keyboard focus. GPUI keyed state exists only while
its element is rendered in consecutive frames. A retained result can leave that
window without losing its source or user-selected code language.

## Decision

Keep the result as the owner of code entities, language choices and copy feedback.
Eviction releases them with the source. Parse table samples in the existing owned
background task; keep scroll handles and font measurements on the UI thread.
Cache measurements by text/font/width and materialize only visible data rows and
code line numbers. The terminal continues to own vertical scrolling.

Compile custom headings/tables in their original Markdown context before passing
inline content to selectable HTML views. Fragments such as `# title` inside a
table remain text. Blocks requiring full-document references or scientific inline
rendering retain the existing document renderer. Raw HTML/media remains literal.
Code reconstruction uses a sufficiently long tilde fence: a language name with a
backtick cannot invalidate it and turn code text into a fetchable image.

Only keys owned by the result container are stopped. Child inputs retain native
character/IME processing; the terminal's existing focus check prevents PTY input.
The filter Escape path clears its query and returns focus to the result.

## Rejected alternatives

- Per-frame extensions or transient code entities: repeat parsing or reset choices.
- Reparse isolated inline fragments as block Markdown: changes their meaning.
- Rewrite shared component internals for terminal-only presentation: unnecessarily
changes unrelated document and settings views.
- Stop every key at the parent: Windows then skips character-message translation.

## Consequences

Code and structured tables retain original copy content. Custom presentation has
bounded state per retained result and additional cold layout work. Synthetic debug
scroll timing is evidence about that fixture, not a release GPU performance claim.

## Validation

Existing native tests cover column ordering, real filter typing, Tab/Enter release,
Escape, copy feedback, raw payloads, viewport retention and PTY isolation. Added
regressions cover unusual code-language fences, inline table semantics and code
entity retention across an alternate-screen round trip. Native checks passed 20
tests with one existing manual timing sample ignored; independent i18n checks pass.

## Supersedes

None. Applies the existing native-result retention and single-viewport decisions.

## Revisit when

The component exposes equivalent semantic block styling or measured document
workloads justify replacing the custom presentation while retaining these behaviors.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Preserve terminal directory output when folding

## Status

Implemented locally after the maintainer canceled directory tables. Targeted
native interaction tests pass; packaged and real desktop responsiveness remain
separate acceptance steps.

## Context

Replacing ordinary directory output with widgets lost the original OSC 8 file
links, including in the widget's plain-text mode. The maintainer also reported
slow row hover and requested original terminal presentation with only the middle
collapsed: keep the first ten and last ten output rows and allow expansion.

## Evidence

Command capture already leaves characters, ANSI attributes and hyperlinks in the
VT grid. A text-only result cannot reconstruct this metadata. Existing projection
slots can shorten a source range, but hiding the entire source hides its links.
Pointer mapping also clamped the inverse-projected source row to the visual
screen size; this redirects hits on the visible tail of a compressed result.

## Decision

Recognized directory commands use an internal grid-fold presentation. Results of
at most twenty physical output rows have no slot or controls. Longer results
replace only their middle range with one control row. The retained full source
range still owns marker/fingerprint validation and eviction.

Expanded results preserve every original row and reserve one control line after
the tenth row by projecting that preceding source row into two display rows while
keeping its original cell painting enabled. Toggling preserves the viewport's
source anchor, rather than following the newly enlarged output tail.

First/tail rows continue through terminal text, color, selection, OSC 8 and pointer
rendering. Inverse pointer bounds and hover anchors use the projected source
range. Link decoration iterates that range, skips hidden rows before producing
cells and advances through sorted matches once instead of scanning all matches
for every cell. Copying a selection across the hidden middle includes its source.

## Rejected alternatives

- Show the old native Raw widget: it contains strings, not original VT attributes.
- Recreate file URIs from filenames: loses the producer's host/path semantics.
- Change the captured range to only the middle: breaks full-source validation.
- Insert or delete terminal rows: changes PTY/cursor/history semantics.

## Consequences

Fold state is per retained result and adds no persisted setting or file lookup.
Source invalidation/eviction restores original terminal output. Row counts refer
to captured physical terminal output, not inferred filesystem entries. Other
Markdown, JSON and Git presentations are unchanged.

## Validation

Real GPUI tests cover a 31-row ANSI/OSC 8 result, exactly eleven hidden middle
rows, first/tail and expanded-middle link actions, complete cross-fold drag-copy,
collapse, prompt hit mapping and absence of PTY input. A twenty-row boundary case
has no native card or fold control. Existing pointer, native-result, link underline
and command-classification checks pass. Desktop hover latency is not inferred
from synthetic-window timing.

## Supersedes

The default directory-table presentation in
`architecture/notes/nebula_terminal/inline_content/2026-10-20-directory-results-and-bounded-tables.md`.
The existing bounded capture and source-validation decisions remain.

## Revisit when

Concrete output formats or reflow behavior require a different source-line boundary,
while preserving original VT metadata and the single terminal scroll owner.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Inline result hover state and natural height

## Status

Implemented; the focused regression fails before the row-identity change and
passes afterward. Physical pointer acceptance accompanies the review.

## Context

JSON row backgrounds followed the pointer only when another event redrew the
result. The following prompt could also acquire extra vertical space after a
native result, even though the underlying terminal output had not added a line.

## Evidence

The pinned GPUI Div implementation creates hover state only for elements with an
element identity. Its Capture listener notifies the current view only when that
state exists. A debug selector does not supply identity. The result's Bubble
mouse-move guard runs after this Capture listener and does not cancel its notify.

The cached-parent regression crosses real JSON row bounds and observes result
notifications before forcing another draw. It fails without row identity. Tests
that force a draw immediately after every pointer move conceal this failure.

The shared projection previously rounded measured height up to an integral
terminal row. This adds up to almost one row of presentation-only space before
subsequent terminal content.

## Decision

Key each row by its source-row index within the owning result. Sorting and
filtering preserve the row's identity while its displayed position changes.
Keep the existing event guard so native controls retain pointer ownership.

Retain fractional row height in the existing source-to-visual projection.
Rendering, source mapping, selection and following prompts continue to use one
projection. Native body padding is symmetric; original shell newlines remain
source data and are not removed to conceal projection padding.

## Rejected alternatives

- Redrawing the whole terminal for every mouse move: hides missing hover state
and spends work even when the pointer stays within the same row.
- Removing the native result's mouse guard: can allow terminal gestures through
the controls without establishing a row's own hover state.
- Resizing the PTY or deleting blank grid rows: changes terminal content to fix
a presentation-space calculation.

## Consequences

Crossing row boundaries now schedules a repaint. CPU totals from the previously
under-redrawing implementation are not a responsiveness target. No parsing or
background discovery is added to hover handling.

## Validation

Thirty reading interaction tests, three projection tests and fifteen pointer
tests passed locally. They cover cached hover notification, actual table heights,
fractional inverse mapping, original directory links, selection, scrolling,
filters, sorting and structured diff controls. Native desktop comparison remains
separate from synthetic-window execution.

## Supersedes

Corrects hover identity and row quantization in the native result renderer.

## Revisit when

The GPUI dependency changes stateless hover invalidation, or the terminal adopts
a different shared coordinate authority.
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Bounded inline result surfaces

## Status

Height, scrolling and view retention are superseded by
`2026-10-19-unified-result-scroll.md`; ordinary command capture is extended by
`2026-10-19-command-output-lenses.md`.

Implemented locally; targeted product and Windows runtime checks passed. This note does not
claim arbitrary stdout conversion or a cross-platform performance result.

## Context

The product needs native Markdown, JSON tables and Git progress at the location of
the command result. Ordinary PTY output remains a VT stream; the existing grid is
display state, not lossless stdout. Its absolute line numbers change during reflow.
Reusing an image's old absolute anchor for an interactive result can cover later
output and route pointer input to the wrong terminal cell.

## Evidence

- `inline_content.rs` defines MIME payloads, frame limits and retention.
- `term/cell.rs` already uses optional shared `CellExtra` for uncommon attributes.
- `event_loop.rs::StreamProcessor::feed` preserves OSC/VT wire order.
- `gpui_shell/terminal/native_results` consumes only visible row markers and owns
all renderers, filtering, sorting, theme and pointer behavior.
- `native_view_cli.rs` supplies an explicit entry from stdin/file or a Git child.
- The pinned component's `TextViewState::push_str` parses streaming appends
asynchronously; `set_text` performs a synchronous full replacement.

## Decision

1. Use the private versioned `OSC 777;pebrel-view;1` extension with Begin/Place/Append/End
frames. This is not advertised as a universal terminal standard or TSP support.
Payload chunks are UTF-8 encoded through Base64. Terminal code owns framing,
storage and placement, not Markdown/table/Git interpretation.
2. The sender writes real CRLFs between Place frames, so ConPTY and the frontend
advance together. The first Windows live trial showed that receiver-only line
insertion let the next command overwrite an earlier result. Native frames
commit pending synchronized VT output before applying placement. Attach a shared content marker only
to each reserved row's first cell, through optional `CellExtra`. Ordinary Cell
size remains unchanged. Markers are nonempty for reflow and line-length purposes.
The registry keeps weak references, so clear/overwrite releases the last marker's
source immediately. Alternate-screen views do not render
primary-screen results. A partially overwritten visible slot is not overpainted.
3. Begin declares a maximum height of 2–40 terminal rows; it initially owns one
row. Place grows the slot sequentially at real column-zero positions, bounded
by that cap. Short Git failures occupy two rows; each visible phase or log
line adds one row plus the command status. The CLI and GUI share the Git model,
including EOF handling. Static tables use their record count; Markdown uses
a bounded source-line estimate, not a claim of exact measured document height.
Slots only grow while producing output and never delete existing terminal
rows. Content exceeding the slot scrolls internally; width follows the pane.
4. Bound a frame at 48 KiB, a source at 4 MiB/4096 nonempty chunks, and retained
sources at 32/16 MiB per stream. Eviction releases raw chunks and becomes an
explicit state on remaining markers. These numbers bound source storage only;
UI strings, parser trees, rows, font/GPU state are additional measured costs.
5. Chunks share references across snapshot boundaries. Source revision controls
incremental consumption. UI entities exist only for currently visible results;
offscreen layout caches are released. Reopening a result can therefore parse
its bounded source again and reset local filter/scroll state.
6. Table parsing and ordering run in background tasks. Query generations reject
obsolete ordering results. Rows are virtualized. Invalid or oversized tables
retain source and present an explicit raw view. Markdown extensions remain
stable across frames to avoid triggering reparsing on every render.
7. Native child controls consume pointer events before the ancestor terminal;
keyboard input stays in the relevant focus owner, with Escape returning to the
terminal. Copy/View/Raw float over the content only while hovered, keyboard
focused or showing clipboard success. Mouse-acquired focus alone cannot pin
the toolbar. Hover does not change the occupied rows. Clipboard success uses
the existing owned feedback lifecycle.
8. `pebrel view --type markdown|table|git` is opt-in. A new local product pane
advertises `PEBREL_NATIVE_RESULTS=1`; other terminals and redirected stdout
use text. `--native` explicitly requests a compatible remote endpoint.
9. `--type git -- git ...` captures stdout/stderr with bounded reader queues.
Stream identity is retained in frames, parser line buffers and raw-view selectors;
arbitrary reads from different pipes are never treated as one original byte stream.
The child uses the C locale for known Git phase parsing. Its exit code supplies
completion status; a phase's 100% does not mean the command succeeded. Shell
command completion closes a still-receiving surface as interrupted.

## Rejected alternatives

- Guess every arbitrary output as JSON/objects: PTY control traffic, partial data
and mixed stderr make that unreliable.
- Store GUI types or arbitrary action scripts in the terminal core: violates the
dependency and trust boundaries.
- Rebuild the entire VT/history model first: the current slice needs bounded
attachments, not a replacement terminal engine.
- Add metadata to every Cell or every historical line: unnecessary permanent cost.
- Reuse absolute image coordinates without reflow handling: stale anchors can
hide unrelated terminal output.
- Treat a browser prototype as evidence of native performance or OS file drag:
those are separate runtime/platform capabilities.

## Consequences

Traditional output is not automatically transformed. Initial inputs are UTF-8
Markdown, JSON object arrays/NDJSON and explicit Git capture. Tables currently
accept at most 20,000 rows/64 columns as native data; larger inputs retain a raw
view within the source budget. Result source is not persisted across app restarts.
Reserved rows remain after source eviction with an explicit unavailable notice.
Native source is not reconstructed by ordinary grid text capture; source copying
belongs to the result view. No automatic remote image or HTML loading is added.

## Validation

Core split-frame/reflow/reset and incremental placement regressions passed locally,
including rejection of gaps, duplicates and non-column-zero placement. The GPUI
regression exercises the real first-row controls: hover, copying, feedback expiry,
raw-view height, mouse/keyboard focus and PTY isolation. It exposed overlap with
the terminal search entry; reserving its hit area keeps the toolbar reachable.
The filtered application suite passed 120 tests with 8 existing ignored tests.
Windows runtime checks passed on the compact revision: consecutive Markdown and
JSON results, a real local Git clone (exit 0), a missing-repository failure (exit
128), and native idle/hover screenshots. The existing Cell-size regression remains
applicable. Visual acceptance by the user and release performance measurements
remain separate from these debug-build checks.

## Supersedes

None. Existing bounded command reading still returns guarded display text and
does not become a raw-byte result API.

## Revisit when

The slice requires exact pixel-measured document height, structured remote file actions,
unbounded data/spooling, persistence, a standard protocol, or measured costs that
invalidate the present budgets. Expand from verified workloads, not from format
names alone.
Loading
Loading