Skip to main content

noot

PyPI version License CI

Test interactive CLIs. Think Stagehand, but for the terminal.

  • f.step("Select 'pyright' from dropdown"): Define CLI interactions in plain English.
  • f.expect("Linting options must contain 'pyright'"): Define expected CLI states in plain English too.
  • assert "pyright" in f.screen().lower(): Or make assertions on CLI state in good ol' Python.
  • Record with LLM once, replay locally and in CI/CD.

Installation

pip install noot

Requires tmux and an ANTHROPIC_API_KEY environment variable.

Quick Start

Scaffold a new project:

noot init

Or add noot to an existing project:

from noot import Flow

def test_create_web_project():
    with Flow.spawn('python setup_wizard.py') as f:
        f.expect('Welcome to Project Setup Wizard')

        f.step("Enter project name 'mywebapp' and press enter")

        # `expect` parses assertions from natural language
        f.expect('Web Application project option is available')

        f.step('Press enter to select Web Application')

        # or specify assertions on screen state directly
        assert "author name" in f.screen()

        f.step("Enter author name 'Alice' and press enter")

Run your tests:

pytest tests/test_cli.py

The first run records LLM responses to the cassette file. Subsequent runs replay from the cassette, so no API calls are made.

API

Method Description
Flow.spawn(cmd) Context manager. Start a CLI process in a managed terminal session
f.step(instruction) Execute a natural language instruction (e.g., "Press enter", "Type 'hello'")
f.expect(condition) Assert the screen matches a natural language condition
f.screen() Return the current terminal output as a string

Recording Modes

Control recording behavior with the RECORD_MODE environment variable:

RECORD_MODE Behavior
once (Default) Record if cassette is missing, replay if it exists.
none Replay only. Fails if a request isn't cached. Use this in CI.
all Always re-record, overwriting existing cassettes.

By default you don't have to think about recording and replay:

pytest tests/test_cli.py
# Subsequent runs will use cache

Example - force re-recording:

RECORD_MODE=all pytest tests/test_cli.py

Example - CI mode (fail if cassette is missing):

RECORD_MODE=none pytest tests/test_cli.py

Cassettes are stored in <project_root>/.cassettes/:

  • CLI cassettes (LLM responses): .cassettes/cli/
  • HTTP cassettes (API recordings): .cassettes/http/

CI/CD

Run tests in CI with RECORD_MODE=none to replay from cached cassettes (no API key needed):

# .github/workflows/test.yml
name: Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Install tmux
        run: sudo apt-get install -y tmux
      - name: Install dependencies
        run: pip install -e ".[dev]"
      - name: Run tests
        run: RECORD_MODE=none pytest

Commit your .cassettes/ directory to version control so CI can replay recordings.

Contributing

Issues and PRs welcome.

License

Apache 2.0

Metadata

Release files for noot 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for noot 0.1.0
File Size Uploaded Provenance Actions
noot-0.1.0.tar.gz 20.2 kB Without provenance Details for noot-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for noot 0.1.0
File Interpreter ABI Platform Actions
noot-0.1.0-py3-none-any.whl Python 3 none any Details for noot-0.1.0-py3-none-any.whl

Total release size: 47.2 kB

Release files / noot-0.1.0.tar.gz

Download URL noot-0.1.0.tar.gz
Size 20.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4f8ef66784734fcf7a961ec1f740ba34a7c14dfce2abfd6b9d4bea1edfad6eff
BLAKE2b-256 checksum
How to use checksums
2b98895f85374ac81b8575c7d40ce7a7dc8d76716184e14af4070ad81451d4d4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / noot-0.1.0-py3-none-any.whl

Download URL noot-0.1.0-py3-none-any.whl
Size 27.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
abb9b8705464f265b596f803192b09a6647398ad59a2a0caac6887e2322fed88
BLAKE2b-256 checksum
How to use checksums
254752fdffef530a41d469dada0cee97dbf8b8bf5b86e788dd7eeb67facbe56d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for noot 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page