Architecture¶
nshell follows a domain-driven, layered design. Each layer depends only on the layers beneath it:
src/
├── domain/ Pure shell logic: parsing, expansion, completion,
│ history, prompting, job-control — no I/O.
├── application/ Use cases: builtins, pipeline execution, job management.
├── infrastructure/ ACLs over the OS: syscalls, PTY, signals, terminal I/O,
│ persistence. SBCL-specific code is isolated here.
└── presentation/ The REPL, line editor (input-state reducer), rendering,
highlighting, autosuggestions, completion UI.
The REPL is structured as a continuation-passing / trampoline loop: each
keystroke runs a pure reducer over an immutable input-state, and rendering is
derived from that state. This keeps the interactive core deterministic and
unit-testable without a terminal. See
Core concepts for what that
buys in practice.
Confining SBCL-specific code to infrastructure/ is what makes the layers
above it portable in principle and testable in practice: a test replaces a
boundary with a value instead of arranging for the operating system to produce
one.
Toolkit foundation¶
nshell builds on the nerima-lisp Common Lisp toolkit family, each wired at the
layer where it fits the domain-driven design:
- cl-parser-kit — its
rule-based tokenizer and Pratt (operator-precedence) parser drive
$((...))arithmetic, which parses to an AST and then evaluates, adding**, bitwise& | ^ ~, shifts<< >>, and the ternary?:. - cl-dataflow — renders
pipelines as validated computation graphs (
pipeline-graph) and models the job lifecycle as an analyzable state machine. - cl-boundary-kit — makes the REPL edge's OS effects (hostname, working directory, clock) explicit, swappable boundaries, so the prompt and command timing are deterministic under test.
- cl-cli — declaratively describes
the
nshellcommand line (--help/--version/-c/script dispatch). - cl-tty-kit — provides Unicode-correct display-width, truncation, and padding, plus the ANSI/SGR escape vocabulary used by rendering, prompt, and completion.
- cl-process-kit — backs timeout-guarded process launch, escalating SIGTERM to SIGKILL across a child's whole process group so a timed-out command substitution leaves no orphaned descendants.
- cl-prolog — the logic engine behind the completion knowledge base.
Test suites¶
Two suites run under cl-weave, both exposed as Nix checks:
nshell/test— the primary regression suite, int/.nshell/weave— a focused suite exercising the completion engine's cl-prolog knowledge base with property-based tests, fixtures, benchmarks, and direct Prolog queries (findall, negation-as-failure, foreign predicates) plus thecl-prolog/weavequery bridge.
Cases that need a real PTY, stty, or external binaries cannot run in the Nix
sandbox and are covered by CI's separate integration job; see
Recipes.