Persistent shell context
Write this so someone with no background can follow.
The problem
Most CLIs establish one implicit context: the working directory (and maybe a remote host over SSH). Everything else — which Google account, which cloud project, which Python venv, which gcloud configuration — lives in parallel stacks the shell does not own.
Symptoms:
-
gcloud config configurations vs Composio’s per-toolkit connected account — two answers to "which Google am I?"
-
REPLs and subshells that replace the prompt and wipe prior context — disorienting
-
Process forks that hijack stdin for "interactive mode" — the default when it should be exceptional
-
Users run commands blind, then discover they acted as the wrong principal
The shell already shows user@host:path — but that is host context, not app context. App context is scattered across env vars, dotfiles, and tool-specific config trees the prompt never surfaces.
Core claim
Persistent context belongs to the shell session, not to each CLI’s private config stack.
When a command needs context that should survive across invocations:
-
The CLI declares required context keys (schema + current value hints)
-
If context is missing, the CLI refuses to proceed — prints a short message and returns a machine-readable context request
-
The shell injects those keys into the prompt as interactive tokens (text, dropdown, autocomplete)
-
Subsequent commands inherit the session context without re-prompting
REPL-style stdin takeover remains available as an explicit mode (--interactive-repl, tool-specific), not the default escape hatch.
This is complementary to Shell Host and Env Refresh (PATH/env freshness) and Host identity as a contract (what machine am I on). Persistent shell context answers: who am I acting as, for which app, in this session?
Relationship to HCI Nerdz
OpenShellOrg owns the protocol, CLI libraries, and Nushell / terminal implementation. HCI Nerdz — Shell context chrome owns the interaction design: token navigation (left-arrow at prompt start), boxed prompt segments, color theming, dropdown vs typeahead affordances.
Cross-link both ways; do not fork competing essays.
Prompt layout (line modes)
Open Shell supports two first-class experimental line modes (see prompt spatial layout):
-
2-line (preferred default) — all contexts on line 1; gutter (with
▶) + command on line 2 -
1-line — gutter (
▶) + contexts + command on one row (muscle-memory / compare)
Switcher lives in the TUI top context bar, not a buried settings page — alongside arrow mode (ephemeral / persist) for gutter ▶ lifetime and copy (see prompt spatial layout).
# 2-line (preferred)
[gcloud: ftn] [py: .venv] rjamd@desk:~/code
[▶] gcloud compute instances list
# 1-line (compare)
[?] [gcloud: ftn] [py: .venv] rjamd@desk:~/code ▶ gcloud compute instances list
| Zone | Notes |
|---|---|
App context (on the context surface) |
Tool-declared keys — grey boxed tokens by default ( |
Host context (stable anchor on the same surface) |
Traditional user@host:path — blue boxed tokens by default |
Input |
Command entry after |
Left-arrow at prompt start cycles focus across context tokens only (never the command buffer). Selected token opens inline editor (typeahead, dropdown, or click-to-expand when the terminal host supports it). Color schemes are theme packs — see HCI Nerdz shell-context-chrome. Default: host = blue subtle boxes; app = grey subtle boxes. Do not paint everything one hue; visual hierarchy must distinguish where from as whom.
Protocol sketch (v0)
Context declaration (CLI 胢↙ shell)
When context is missing or invalid, exit non-zero and emit one JSONL row (aligned with nu-emit patterns):
{
"type": "shell-context-request",
"namespace": "gcloud",
"keys": [
{
"id": "configuration",
"label": "Configuration",
"kind": "enum",
"options": ["default", "ftn", "personal"],
"current": null,
"required": true
},
{
"id": "project",
"label": "Project",
"kind": "string",
"suggest": ["my-prod", "my-dev"],
"required": true
}
],
"message": "Set gcloud context in the shell prompt, then retry."
}
Shell parses stderr or a dedicated fd (TBD — prefer structured stderr line tagged with a magic prefix so pipes stay clean).
Context binding (shell session)
Shell stores bound values in session state (Nushell $env overlay or dedicated $context record). Export to child processes as namespaced env vars, e.g. OSO_CTX_GCLOUD_CONFIGURATION=ftn.
SOS integration
Context keys may also appear as SOS flags (--context-gcloud-configuration=ftn). If provided on the command line, the CLI validates, updates shell session state, and proceeds — without treating them as one-shot flags.
Libraries in shell-context (planned) reclassify declared context flags out of the ephemeral argv bucket.
stdin / REPL modes
| Mode | When |
Negotiated context (default) |
Missing context 胢↙ request + exit; shell prompt owns persistence |
|
Ephemeral flag |
One-shot override; does not write session unless --persist-context |
|
Interactive REPL |
Explicit; tool owns the screen; shell context frozen visible in host chrome |
Repositories (planned)
| Repo | Role |
|---|---|
openshellorg/shell-context |
Spec (SDL schema), polyglot libs (C, C++, D, Rust), reference adapters |
openshellorg/open-shell |
Dlang shell — default OSO mode, compatibility parsers, layers, context |
openshellorg/terminal (fork) |
Host-level context bar when inline prompt editing needs GUI dropdowns (see shell-host) |
HCI-Nerdz/shell-context-demo |
Web mockup — core + controller + DOM renderer per HCI prototype strategy |
DevCentr toolchain-advisor / docs |
Recommend context setup; reference gcloud / Composio divergence in practitioner docs |
Open Shell runtime (D)
Primary implementation: Open Shell in Dlang. Default session mode is Open Shell syntax; u, ash, and future modes are compatibility parsers, not the product default.
Upstream Nushell (Rust) is the behavioral baseline for u mode — parity fixtures, display formatting reference — not the runtime for default mode.
Prohelp integration
Prohelp is shell-agnostic — not bundled with Open Shell. See Prohelp and prompt gutter for the full integration model.
Automatic help (input buffer)
When the input buffer matches a prohelp topic (matchPrefix / detectPattern), Open Shell shows a gutter ? on the display overlay — no --help typing required.
This is the primary trust affordance: help appears when the shell recognizes the command.
Context-scoped help (tokens)
Help SDL may declare requiresContext: [gcloud.configuration, gcloud.project].
When the user focuses a context token and invokes help (?, gutter button, or bound key), prohelp scopes topics to that namespace.
Context-row gutter
When persistent context is visible on its own row, gutter ? leads that row — same overlay rules as the input-line gutter.
Focused context wins for topic scope; input match controls visibility.
Ship gutter auto-detect in Open Shell first; extend the standalone prohelp wrapper docs afterward.
Reference adapters (v1 targets)
-
gcloud — configuration + project + account (motivating case)
-
Python venv / uv — interpreter + venv path
-
aws / az — profile + subscription (same pattern)
-
Composio-connected toolkit identity — document mapping, not duplication
Non-goals (v1)
-
Replacing Composio or OAuth flows — shell context is session binding, not credential storage
-
A global cross-machine context sync service
-
Mandating every CLI on day one — certification path via SOS + {OSO} Certified
Publication sequence
-
Spec + seed — this page + private plan seed in openshellorg/project-plans
-
HCI essay + web demo — interaction chrome, themes, left-arrow token focus
-
shell-context repo — SDL schema + C/D lib stub + gcloud adapter sketch
-
Nushell fork spike — render one app token + session bind
-
DevCentr cross-link — toolchain docs, Composio vs gcloud practitioner note
Related
-
Future topics — promoted from speculative once env-refresh ships
-
Context-bound settings — same dependent context pattern for GUI admin surfaces