Skip to content

Custom Commands

Test REPLs and interactive shells using cmd="..." to keep a subprocess running across commands within a block.

Basic Usage

markdown
```console cmd="node -i"
$ 1 + 1
2
$ 'hello'.toUpperCase()
'HELLO'
```

A single subprocess is started for the block. Commands are sent to stdin and output is captured from stdout. State persists between commands within the block.

PTY vs Pipe Mode

On POSIX systems (macOS, Linux), mdspec uses PTY mode by default, giving the subprocess a real terminal (isTTY = true). This enables TTY-aware features like colors, prompts, and OSC 133 completion detection.

Force pipe mode with pty=false when you need separate stderr capture:

markdown
```console cmd="my-repl" pty=false
$ command-that-logs-to-stderr
expected stdout only
```
PTY (default on POSIX)Pipe (pty=false or Windows)
Subprocess seesisTTY=trueisTTY=false
OSC 133Auto-detectedRequires TERM_SHELL_INTEGRATION=1
stderrMerged with stdoutSeparate stream
PlatformmacOS, LinuxAll platforms

OSC 133 Completion Detection

Programs that emit OSC 133 shell integration sequences signal command completion immediately, making tests deterministic and fast (~6x faster than silence-based detection).

To support this in your REPL:

typescript
// After command output, emit completion marker with exit code
if (process.stdout.isTTY) {
  process.stdout.write(`\x1b]133;D;${exitCode}\x07`)
}

Without OSC 133, mdspec falls back to silence-based detection -- waiting for output to stop for a configurable duration.

Timing Options

OptionDefault (PTY)Default (Pipe)Description
startupDelay300ms0msMax wait for subprocess to be ready
minWait50ms100msSilence duration to assume completion
maxWait2000ms2000msMaximum wait before timeout
markdown
```console cmd="slow-repl" startupDelay=500 minWait=200 maxWait=5000
$ slow-command
expected output
```

Detection Flow

Ready detection (before sending a command):

  1. OSC 133;A marker detected -- immediate ready
  2. Any output received -- subprocess started, proceed
  3. startupDelay elapsed -- timeout, proceed anyway

Completion detection (after sending a command):

  1. OSC 133;D marker detected -- immediate completion
  2. minWait ms of silence -- assume complete
  3. maxWait ms elapsed -- timeout

Use Cases

  • Testing REPLs where state persists (Node.js, Python, etc.)
  • Testing TUI shells with in-memory state
  • Any interactive command-line tool with a prompt-response pattern