{"id":50703840,"url":"https://github.com/vurte/tui-td-py","last_synced_at":"2026-06-09T10:01:45.633Z","repository":{"id":363121074,"uuid":"1262034101","full_name":"vurte/tui-td-py","owner":"vurte","description":"Official Python wrapper for tui-td — TUI testing and automation for coding agents and terminal-based AI tools.","archived":false,"fork":false,"pushed_at":"2026-06-07T13:53:13.000Z","size":29,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T15:22:57.517Z","etag":null,"topics":["ai-agents","async","automation","mcp","python","terminal","testing","tui","tui-testing"],"latest_commit_sha":null,"homepage":"https://github.com/vurte/tui-td-py","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vurte.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-07T13:39:46.000Z","updated_at":"2026-06-07T13:53:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vurte/tui-td-py","commit_stats":null,"previous_names":["vurte/tui-td-py"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/vurte/tui-td-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vurte%2Ftui-td-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vurte%2Ftui-td-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vurte%2Ftui-td-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vurte%2Ftui-td-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vurte","download_url":"https://codeload.github.com/vurte/tui-td-py/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vurte%2Ftui-td-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34101070,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","async","automation","mcp","python","terminal","testing","tui","tui-testing"],"created_at":"2026-06-09T10:01:44.988Z","updated_at":"2026-06-09T10:01:45.627Z","avatar_url":"https://github.com/vurte.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tui-td-py\n\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\nOfficial Python wrapper for [tui-td](https://github.com/tui-td/tui-td) — TUI testing and automation for coding agents and terminal-based AI tools.\n\n**tui-td-py** communicates with the `tui-td serve` MCP server via JSON-RPC 2.0 over stdio. Start any TUI in a virtual terminal, send input, and analyze output — as structured Python objects, plain text, PNG screenshots, or HTML renders.\n\n## Prerequisites\n\n| Software | Minimum | Installation |\n|----------|---------|-------------|\n| **Python** | 3.10+ | [python.org](https://python.org) or `brew install python` |\n| **Ruby** | 3.0+ | [rbenv](https://github.com/rbenv/rbenv) or `brew install ruby` |\n| **tui-td** (Ruby gem) | 0.2.21+ | `gem install tui-td` |\n\n```bash\n# Install Ruby via rbenv (recommended) or brew\nrbenv install 3.4.2     # https://github.com/rbenv/rbenv\n# or: brew install ruby  # https://brew.sh\n\n# Install tui-td\ngem install tui-td\n\n# Verify\ntui-td --version\n# =\u003e tui-td 0.2.21\n```\n\n## Installation\n\n```bash\npip install git+https://github.com/vurte/tui-td-py.git\n```\n\n## Quick Start\n\n```python\nimport asyncio\nfrom tui_td import TUIDriver\n\n\nasync def main() -\u003e None:\n    async with TUIDriver(\"echo 'Hello World'\", rows=5, cols=80) as tui:\n        await tui.wait_for_stable()\n        text = await tui.plain_text()\n        print(text)\n\n\nasyncio.run(main())\n```\n\nMore examples in [`examples/`](examples/):\n- [`basic_tui_driver.py`](examples/basic_tui_driver.py) — States, Search, Elements, Screenshot\n- [`interactive_session.py`](examples/interactive_session.py) — Send/Wait/Respond Workflow\n- [`snapshot_diff.py`](examples/snapshot_diff.py) — Before/After Snapshots + Diff\n\n## Usage\n\n### Start and Stop\n\n```python\n# Context manager (recommended)\nasync with TUIDriver(\"my_tui_app\") as tui:\n    ...\n\n# Manual lifecycle\ntui = TUIDriver(\"my_tui_app\")\nawait tui.start()\n# ... use tui ...\nawait tui.close()\n```\n\n### Send Input\n\n```python\n# Send text (use \\n for Enter)\nawait tui.send(\"hello\\n\")\n\n# Send special keys\nawait tui.send_key(\"enter\")\nawait tui.send_key(\"up\")\nawait tui.send_key(\"ctrl_c\")\nawait tui.send_key(\"escape\")\n```\n\n### Read State\n\n```python\n# AI-friendly compact state (text + highlights)\nstate = await tui.state(\"ai\")\nprint(state.text)\nfor hl in state.highlights:\n    print(f\"  row {hl.row}: {hl.text} (bold={hl.bold}, fg={hl.fg})\")\n\n# Full cell grid with colors\nfull = await tui.state(\"full\")\nfor row in full.rows:\n    for cell in row:\n        if cell.fg != \"default\":\n            print(f\"Colored char: {cell.char} fg={cell.fg}\")\n\n# Plain text only\ntext = await tui.plain_text()\n```\n\n### Wait Operations\n\n```python\n# Wait for specific text to appear\nawait tui.wait_for_text(\"\u003e \", timeout=10)\n\n# Wait for output to stabilize (300ms of silence)\nawait tui.wait_for_stable()\n\n# Wait for process to finish\nexit_code = await tui.wait_for_exit()\n```\n\n### Search and Elements\n\n```python\n# Search for text or regex\nmatches = await tui.find_text(\"ERROR\", match=\"partial\")\nfor m in matches:\n    print(f\"Found at [{m.row},{m.col}]: {m.full_line}\")\n\n# Find UI elements by role\nbuttons = await tui.find_elements(role=\"button\")\ndialogs = await tui.find_elements(role=\"dialog\")\ninputs = await tui.find_elements(role=\"input\")\n\n# Element with filters\nchecked = await tui.find_elements(role=\"checkbox\", checked=True)\n\n# Get actions for an element\nactions = await tui.element_actions(\"button\", text=\"OK\")\nprint(actions)\n```\n\n### Screenshots and HTML\n\n```python\n# PNG screenshot\npath = await tui.screenshot()\nprint(f\"Screenshot: {path}\")\n\n# HTML render (inline)\nhtml = await tui.html_render()\n\n# HTML render (save to file)\nawait tui.html_render(\"/tmp/output.html\")\n```\n\n### Snapshots and Diff\n\n```python\n# Save a named snapshot\nawait tui.save_snapshot(\"login_screen\", type=\"text\")\n\n# Assert current state matches (creates on first run)\nresult = await tui.assert_snapshot(\"login_screen\")\nprint(result)\n\n# Diff against a previously saved state\ndiff = await tui.diff(previous_state_data, chars_only=True)\n```\n\n### Video Recording\n\n```python\n# Start recording\nawait tui.record_start(\"/tmp/session.mp4\", framerate=30)\n\n# ... interact with the TUI ...\n\n# Stop and finalize\nvideo_path = await tui.record_stop()\n```\n\n## API Reference\n\n### TUIDriver\n\n| Method | Description |\n|--------|-------------|\n| `start()` | Start the TUI and connect to MCP server |\n| `close()` | Close the TUI and clean up |\n| `send(text)` | Send text (use `\\n` for Enter) |\n| `send_key(key)` | Send special key (`enter`, `tab`, `up`, etc.) |\n| `state(format)` | Get terminal state (`\"ai\"`, `\"full\"`, `\"text\"`) |\n| `plain_text()` | Get plain text content |\n| `screenshot(path?)` | Capture PNG screenshot |\n| `html_render(path?)` | Render as HTML |\n| `wait_for_text(text, timeout?)` | Wait until text appears |\n| `wait_for_stable(timeout?)` | Wait for output to stabilize |\n| `wait_for_exit()` | Wait for process exit |\n| `check_exit_status()` | Query exit status |\n| `find_text(pattern, match)` | Search for text/regex |\n| `find_elements(**filters)` | Find UI elements |\n| `element_actions(role, text?)` | Get actions for an element |\n| `diff(snapshot, chars_only?)` | Compare against snapshot |\n| `annotate_element(role, row, col, ...)` | Register a custom element |\n| `save_snapshot(name, type?)` | Save named snapshot |\n| `assert_snapshot(name, type?)` | Compare against named snapshot |\n| `record_start(path, ...)` | Start video recording |\n| `record_stop()` | Stop video recording |\n| `record_status()` | Check recording status |\n\n### Supported Keys\n\n`enter`, `tab`, `escape`, `up`, `down`, `left`, `right`, `backspace`,\n`ctrl_c`, `ctrl_d`, `ctrl_z`, `page_up`, `page_down`, `home`, `end`,\n`delete`\n\n### State Formats\n\n| Format | Model | Description |\n|--------|-------|-------------|\n| `\"ai\"` | `AIStateData` | Compact: text + highlights + summary (default) |\n| `\"full\"` | `FullStateData` | Complete cell grid with ANSI colors |\n| `\"text\"` | `str` | Plain text only |\n\n## Development\n\n```bash\n# Install dev dependencies\npip install -e \".[dev]\"\n\n# Run tests\npytest\n\n# Lint + format\nruff check tui_td/ tests/\nruff format tui_td/ tests/\n\n# Type check (strict)\nmypy tui_td/\n\n# Install pre-commit hooks\npre-commit install\n```\n\n## Further Documentation\n\n- [Architecture \u0026 Data Flow](docs/architecture.md) — How tui-td-py communicates with tui-td\n- [API Reference](docs/api.md) — Complete methods, models, and exceptions\n- [Examples](examples/) — Runnable demo scripts\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvurte%2Ftui-td-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvurte%2Ftui-td-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvurte%2Ftui-td-py/lists"}