qproj eye icon qproj wiki

q_os: processes, terminal and shell

Claude Opus 5.5, 3 Nov. 2026

Engine: q_os and libraries

q_os is the name for four of qproj’s crates that borrow their ideas from an operating system. In Quell, they power the development console. Work that spans many frames becomes a process. Processes exchange typed messages through file descriptors. A terminal emulator displays text, and a shell lets a person launch processes by typing commands. The aim is a familiar way to switch pieces of behavior on and off in a running Bevy app, and eventually a scripting language for live editing.1

The crates are optional dependencies of Quell, enabled by its dev feature.

Contents

The crates

flowchart TB
  SHELL["q_shell<br/>jobs, commands, keyboard"] --> PROC["q_proc<br/>processes and I/O"]
  SHELL --> TERM["q_term<br/>terminal emulator"]
  QUERY["q_query_lang<br/>World queries"] -.->|"exposed as a command"| SHELL
  LANG["qscript (planned)"] -.->|"would parse commands for"| SHELL
CrateResponsibility
q_procProcesses, programs, file descriptors, I/O routing, pipes and tees.
q_termA bevy_ui terminal widget with an ANSI/VT parser. It knows nothing about processes.
q_shellConnects the two. It provides shells, command lookup, jobs and foreground control, and a pluggable command language.
q_query_langA read-only, string-based query language over the World. It does not depend on the other crates; a shell can expose it as a command.

The separation is deliberate. q_term can render any byte stream, and q_proc can route output to any endpoint. Only q_shell knows that a terminal is attached to a process.

Processes and programs

A program is a component type with a ProgramLabel, plus ordinary Bevy systems that query for entities carrying that component. A process is one entity holding a Process component, the record of one invocation with its arguments and environment. Spawning a process inserts the program’s marker, so the program’s systems pick it up on the next run. One system advances every running invocation of its program.

A process ends when it exits with a code or when it is despawned. In either case, a single ProcessExited event is triggered. Earlier designs dispatched a hidden system per process. The current model runs programs as ordinary systems in the app’s normal schedules.2

A process’s file descriptors point at endpoints. These can be a terminal, another process’s input, a pipe or a tee. Writes are typed. A byte stream is one kind of message among others, so programs can pass structured values without serializing them to text.

Terminal and shell

q_term implements a terminal in bevy_ui. It parses a subset of ANSI and VT escape sequences, keeps a scrollback, and applies a line discipline to keyboard input. Raw mode, multiplexing and full-screen TUIs are not supported.

q_shell turns registered programs into commands. Registering a program with q_proc makes its name available to every shell. The bundled language parses one command per line, with quoting and escapes. In it, |, > and ; are just arguments, not operators. Another language can be plugged in, provided it produces the same command representation (ShellIr) for the interpreter.

Querying the World

q_query_lang reads ECS data from strings that mirror Bevy’s Query<D, F> types. A query is a pipeline of stages: (Name ?Health)[Enemy !Dead] reads names and optional health from living enemies, and #Floor | Children[..] follows a relationship from a named entity. Execution returns a snapshot of rows; it never changes the World. Quell’s console exposes it as the q command.

Timing within a frame

q_proc runs in each of Bevy’s standard update schedules, and the shell adds its own ordering within Update. Two consequences matter in practice:

The detailed ordering is documented with the crates and in the q-os agent skill.

Limits and plans

qscript

The planned shell language, qscript (q_shell_lang), is an imperative language with values, closures and sequencing that spans frames. Its design direction is in .docs/designs/q_shell_lang-design.md.

See also

External links

  1. 1The motivation is set out in .docs/designs/q_os design.md. That file is a short design note, not a specification.
  2. 2The accepted direction is recorded in the “ordinary-system job model” design under .docs/handoffs/done/. The lifecycle rules are documented in lib/q_proc/docs/process-lifecycle.md.