# shout Transcript-based shell integration test runner. Bun + TypeScript. ## Commands - `bun test` — run unit tests - `bunx tsc --noEmit` — type check - `bun run src/cli/index.ts test [files...]` — run shout CLI - `-u, --update` — rewrite `.shout` files with actual output - `-k, --keep` — keep temp directories after run - `--clean-env` — start with empty environment - `--path ` — prepend to `$PATH` (repeatable) - `--timeout ` — per-command timeout (default `10s`) - `-v, --verbose` — print each command as it runs - `--port-from ` — auto-assign `$PORT` starting from n - `--parallel` — run files in parallel ## Architecture - `src/parse.ts` — parses `.shout` files into `ShoutFile` (list of `Command`) - `src/run.ts` — executes commands via `Bun.spawn(["/bin/sh"], { detached: true })`, captures output with sentinels - `src/match.ts` — wildcard-aware output matching and diff generation - `src/format.ts` — evaluates pass/fail, formats failures and summary - `src/update.ts` — rewrites `.shout` files with actual output (`--update` mode) - `src/duration.ts` — parses duration strings (`10s`, `500ms`, `1m`) - `src/cli/index.ts` — CLI entry point via `commander` - `src/index.ts` — barrel exports - `web/index.html` — web documentation page ## .shout file format - `$ ` prefix = command to execute - Lines between commands = expected output (stdout+stderr merged) - `...` on its own line = multi-line wildcard (matches zero or more lines) - `...` inline = matches any characters on that line - `[N]` on last line of expected output = assert exit code N - `[*]` = assert any non-zero exit code; default expects 0 - `#` after a command = comment (stripped); `#` in expected output is literal - `@env KEY=VALUE` before first command = set environment variable - `@setup path.shout` before first command = prepend commands (and `@env`) from another file - Setup files use a plain format: each line is a command (no `$ ` prefix), `#` lines are comments, blank lines ignored - Setup files can contain `@env` directives but not `@setup` (no nesting) - User file `@env` overrides setup file `@env` - Setup command failures abort the test with an error - Each file runs in a fresh temp dir with a single `/bin/sh` session - `$HOME` and `$SHOUT_DIR` are set to the temp dir automatically - `$SHOUT_SOURCE_DIR` is set to the directory containing the `.shout` file - `$SHOUT_PROJECT_DIR` is set to `cwd` where `shout` was invoked - stdout and stderr are merged (`exec 2>&1`) ## Style - Strict TypeScript, Bun runtime - No classes — plain functions and types - Tests in `src/*.test.ts`, example `.shout` files in `test/`