Shell display and control layers :: Shell Architecture :: OpenShellOrg Docs

Shell display and control layers

Write this so someone with no background can follow.

The problem

Classic shells multiplex everything onto one byte stream:

  • stdout carries both pipeline data and incidental UI

  • stdin is either shell input or a child REPL — no middle ground

  • Pasted multi-line instructions run blind; partial failure leaves the session poisoned

  • Startup motd is hacked together from profile scripts with no layout model

  • Switching UNIX syntax vs structured-shell syntax means spawning another process in another tab

The thesis page already argues for separating transport from presentation. This page commits the product plan: a layered shell host where TUIs render on overlays that do not become part of the stdout record.

Naming (proshell vs alternatives)

Do not ship proshell as the product name.

Prohelp is intentionally shell-agnostic — it installs a help wrapper for bash, zsh, fish, Nushell, and PowerShell. Naming the enhanced shell proshell invites the false belief that prohelp only works there, which shrinks prohelp adoption and shrinks shell adoption at the same time.

Prohelp and the layered shell are sibling OSO products, not a bundle.

Name Use Verdict

Open Shell (runtime)

User-facing name on opensh.org; the Nushell fork + terminal host experience

Preferred public name

openshellorg/nushell (fork)

Implementation repo — same pattern as openshellorg/terminal

Preferred engineering home

ctxshell / shell-context

Internal name for context-token + session-bind features

Good for libraries and code; narrow scope

preshell

Essay/concept label — ideas that should have predated the REPL-as-default shell

Good for HCI writing; not a binary name

proshell / prosh

Sounds like prohelp sibling bundle

Avoid as product name

nu (upstream binary)

When running vanilla Nushell without OSO layers

Keep distinct from Open Shell fork

Invocation: users can still type nu or open-shell (TBD); no need for a new four-letter command unless marketing demands it.

Layer stack (bottom to top)

Layer Owns stdout record?

Base (command line + job output)

Parsed input, pipeline execution, structured rows to screen

Yes — this is the audit trail

Display overlay

Paste preview, startup layout, progress/checklist for multi-step paste, transient TUI chrome

No — ephemeral; captured separately if user opts in

Control plane (invisible)

Key routing, mode swap, cancel/intercept, focus target (token vs input vs overlay)

N/A

Context chrome (prompt; 1-line / 2-line modes)

Persistent context tokens — persistent shell context

Prompt line only; not mixed into child stdout

Host chrome (terminal fork)

GUI promotion for dropdowns — shell-host

N/A

Child processes write to base layer only unless they explicitly request an overlay (future protocol). Overlays never append to the pipe when the user pipes output to a file.

Prompt gutter (display overlay)

The prompt gutter is part of the display overlay — a reserved left band before context tokens:

  • Renders on overlay cells, not stdout

  • Default width 2–3 monospace columns (gutterWidthHint per theme)

  • Shell-owned chrome for ? (prohelp), ▶ (line grabber), ▪ / A`–`Z (simple choice lists)

[?] [gcloud: ftn ▾]  user@host:path ›
 ^ gutter (overlay)

Deprecated: tools printing >, bullets, or menu markers via printf when the shell can own gutter content instead. Complex formatting stays in prohelp TUI and framework overlays.

Paste preview overlay

Motivation

Pasting a multi-line script into Nushell (or bash) often:

  • Parses slowly with no feedback

  • Runs line-by-line with silent failure mid-sequence

  • Leaves partial side effects when the user aborts late

A warning line is not enough. Users need to see the block before it executes.

Behavior

When the input buffer detects a paste (bracketed paste or heuristic newline burst):

  1. Display overlay opens at the top of the pane (not stdout)

  2. Shows up to 5 visible lines of the pasted block inside a TUI outline/frame

  3. PgUp / PgDn scroll the preview (unused by default in most shells — reclaim here)

  4. User confirms (Enter) or rejects (Esc / dedicated cancel)

  5. On confirm, base layer receives the block as input; overlay closes

During execution of a confirmed multi-line block:

  1. Overlay may shrink to a step tracker — lines check off as they complete

  2. Failures highlight the failing step without erasing prior output on base layer

  3. Cancel (Ctrl+C) routes through control plane — see Cancel semantics

Cancel semantics

Ctrl+C during preview → discard entire paste; base layer untouched.

Ctrl+C during stepped execution → control plane asks: abort remaining steps only, or roll back (when tools expose undo hooks)? Default v1: abort remaining; document which side effects may remain (honest messaging).

Control plane (input routing)

The control plane sits above consumer layers:

Keys -> Control plane -> { overlay focus | prompt token | base input | mode toggle }
  • When overlay is open, keystrokes go to overlay first (scroll, confirm, cancel)

  • When a context token is focused, keys edit the token (context chrome)

  • Otherwise keys go to base command input

  • Global chords bypass focus when marked always-on (mode swap, home)

This replaces the false choice between shell mode and REPL owns stdin.

Syntax modes (default + compatibility)

Open Shell (Dlang runtime) keeps one session and swaps syntax mode — not separate shell processes.

Mode Accepts Default?

oso

Open Shell native syntax, structured pipelines, OSO layers/context

Yes — session starts here

nu

Nushell compatibility (reproduced baseline in D)

No — explicit switch

bash

Classical pipes, $VAR, &&, heredocs (bash-ish)

No — explicit switch

fish, zsh (planned)

Additional compatibility parsers

No

UI labels use concrete names (bash, nu, oso) — not vague UNIX.

Swap without nested PTY:

  • UI: mode selector (dropdown) in Ctrl+1 slot

  • Keyboard: Ctrl+PgUp / Ctrl+PgDn cycle modes

  • Prompt grey token: mode: oso / mode: nu / mode: bash

See Open Shell for baseline vs default formatting rules.

Reserved always-on chords (OSO defaults)

Subject to shell keybindings comparison — these aim for unused defaults:

Chord Action

Ctrl+PgUp / Ctrl+PgDn

Cycle syntax mode (UNIX vs structured)

Ctrl+1

Mode selector (click or menu) — primary always-on slot

Ctrl+2Ctrl+0

Reserved for future always-on toggles (context pin, overlay pin, etc.)

Ctrl+ + backtick

Return-to-home — reset cwd to session home (not Ctrl+H — taken)

Ctrl+/

Command palette / chord help

PgUp / PgDn (overlay open)

Scroll paste preview

Ctrl+Enter (structured mode)

Insert line above current line in multiline buffer (bash does this; Nu currently no-ops — reclaim)

Startup layout document

Replace ad-hoc profile echo chains with a startup layout document (SDL or AsciiDoc subset):

  • Rendered on the display overlay at session start

  • Disappears after first command or timeout — not part of stdout log

  • User-editable file (~/.config/open-shell/startup.adoc or similar)

  • Supports columns, links, context summary, env-health banner (pairs with env-refresh)

Profile scripts still run for side effects (PATH, env); layout doc is presentation only.

Relationship to prohelp

Prohelp integrates at the gutter + context + overlay layers (see Prohelp and prompt gutter):

  • Auto-detect: input buffer match → gutter ? appears (no --help typing)

  • Manual: help / ? routes through prohelp for PATH topics

  • Context token focused → prohelp scopes help to that namespace; gutter ? on context row

Prohelp does not require Open Shell. Open Shell does not require prohelp (degraded help falls back to man).

Repositories

Same fork strategy as persistent shell context:

  • openshellorg/open-shell — Dlang runtime: layers, control plane, paste preview, syntax modes

  • openshellorg/terminal — host chrome for toggles and GUI promotion

  • HCI Nerdz demo — overlay interaction mockups

Top context bar placement (mode-engaged)

The always-on top context bar prefers native host chrome when the parent terminal accepts it — inserted into host chrome, not hovered over the shell. Otherwise it renders on this page’s display overlay stack. See host chrome negotiation (probe / offer / accept/reject / render).

App top bars and hover widgets (color picker, GUI editor, file upload, …​) are a separate channel: host native widgets.

Retro-interactive results (structured data)

When the base layer paints structured rows (Nushell tables, API lists), prefer format at display time and keep the result block retro-interactive after the command exits: horizontal scroll, expand row, filter — not frozen VT text.

That upgrades shell data. Compilers and long adversarial diagnostics belong on Tool Runs instead. Per-command channel switchers keep stdout / stderr un-weaved while either path runs.