Metadata-Version: 2.4
Name: auto-yes
Version: 0.16.0
Summary: Automatically respond 'yes' to interactive CLI prompts via PTY proxy
Project-URL: Homepage, https://github.com/clemente0731/auto-yes
Project-URL: Documentation, https://github.com/clemente0731/auto-yes#readme
Project-URL: Repository, https://github.com/clemente0731/auto-yes
Project-URL: Issues, https://github.com/clemente0731/auto-yes/issues
Project-URL: Changelog, https://github.com/clemente0731/auto-yes/blob/main/CHANGELOG.md
Author: auto-yes contributors
License-Expression: MIT
License-File: LICENSE
Keywords: automation,cli,interactive,prompt,pty,terminal,yes
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pre-commit>=3.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest-timeout>=2.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: windows
Requires-Dist: pywinpty>=2.0; extra == 'windows'
Description-Content-Type: text/markdown

# auto-yes

> **Auto-respond to AI CLI prompts. Never get blocked by interactive yes/no dialogs again.**

[![PyPI version](https://img.shields.io/pypi/v/auto-yes.svg)](https://pypi.org/project/auto-yes/)
[![Python](https://img.shields.io/pypi/pyversions/auto-yes.svg)](https://pypi.org/project/auto-yes/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-270%20passed-brightgreen.svg)](#development)
[![Platforms](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-blue.svg)](#platform-support)

`auto-yes` wraps any CLI command in a **PTY (pseudo-terminal) proxy**, watches the output stream for interactive prompts and automatically injects the correct response — so your overnight AI agent loops, CI scripts, and automation pipelines never block waiting for a human.

Works out-of-the-box with **Claude Code**, **Cursor Agent**, **Gemini CLI**, **OpenAI Codex**, **GitHub Copilot**, **Amazon Q**, **Aider**, and 10+ more AI CLI tools. Also handles generic `[y/n]`, `Continue?`, SSH fingerprint, Terraform `yes`, and any custom regex you define.

```
╭─ without auto-yes ─────────────────────────────────────────╮
│  claude "refactor auth module"                              │
│  > Trust this folder?  1. Yes  2. No   ← blocks forever   │
╰─────────────────────────────────────────────────────────────╯

╭─ with auto-yes ────────────────────────────────────────────╮
│  auto-yes claude "refactor auth module"                     │
│  > Trust this folder?  1. Yes  2. No                       │
│  [auto-yes] responded 'y' (matched: ❯ 1. Yes, I trust…)   │
│  ✓ Continuing automatically…                               │
╰─────────────────────────────────────────────────────────────╯
```

---

## Installation

```bash
pip install auto-yes
```

Windows users — for full PTY support add the optional extra:

```bash
pip install auto-yes[windows]
```

---

## Quick start

### Wrap an AI CLI tool directly (recommended)

```bash
auto-yes claude "fix the tests"          # wraps: claude "fix the tests"
auto-yes cursor chat "add unit tests"    # wraps: agent chat "add unit tests"
auto-yes gemini "review this PR"         # wraps: gemini "review this PR"
auto-yes codex "explain this function"   # wraps: codex "explain this function"
auto-yes aider --model gpt-4o           # wraps: aider --model gpt-4o
auto-yes copilot                         # wraps: gh copilot
auto-yes amazonq chat "help me"          # wraps: q chat "help me"
```

The profile name maps to the real binary automatically — run `auto-yes list` to see all profiles.

### Overnight / automation mode (`--auto`)

For **unattended overnight runs** in corporate environments where `--dangerously-skip-permissions` is restricted:

```bash
# load ALL AI profiles, near-zero cooldown (0.05s), verbose logging
auto-yes run --auto -- claude --dangerously-skip-permissions "work through the backlog"

# or pipe through a loop
for task in tasks/*.md; do
    auto-yes run --auto -- claude "$(cat $task)"
done
```

`--auto` automatically:
- Loads patterns for **all** supported AI CLI tools
- Sets cooldown to **0.05s** (fast batch mode)
- Enables **verbose** logging so you can audit what was approved

### Heartbeat / keepalive (`--heartbeat`)

Send Enter automatically every N seconds of inactivity to keep Claude / Cursor Agent responsive
when it is waiting for confirmation but no prompt pattern was matched:

```bash
# Shell mode: send Enter every 30s while idle
auto-yes --on --heartbeat 30

# Wrap mode: same, wrapping claude directly
auto-yes claude --heartbeat 30 "refactor the auth module"

# Combine with --auto for unattended overnight runs
auto-yes run --auto --heartbeat 30 -- claude "work through the backlog"
```

The timer resets on every real keystroke, so it never fires while you are actively typing.

### Shell session mode

Start a persistent shell where every prompt is auto-answered:

```bash
auto-yes --on --cli claude
# → now inside an auto-yes session; type normally, prompts are handled
exit
```

### Single-command mode

```bash
auto-yes run -- apt install nginx
auto-yes run --cli claude --cooldown 0.2 -- claude "fix tests"
auto-yes run --cli all -- ./deploy.sh   # match every AI tool + generic
```

### Interactive shell session (`shell` alias)

```bash
auto-yes shell --cli claude --cli generic   # same as --on, more intuitive
```

### Human-in-loop session control

Control a running auto-yes from **another terminal** — pause mid-run for manual interaction, then resume:

```bash
# Terminal 1: running auto-yes
auto-yes run --auto -- claude "big refactor"
# [auto-yes] PID: 12345  toggle: auto-yes toggle 12345

# Terminal 2: you want to take over for a moment
auto-yes ls                   # see running sessions and PIDs
auto-yes toggle 12345         # pause (prompts pass through to you)
# ... interact manually ...
auto-yes toggle 12345         # resume auto-responses

# Or use pause/continue explicitly:
auto-yes pause 12345
auto-yes continue 12345
auto-yes pause all            # pause every session
auto-yes continue all         # resume all
```

### Status

```bash
auto-yes status            # check if active in current shell
auto-yes ls                # list all running sessions with PID, profile, uptime
```

---

## How it works

```
┌──────────────────────────────────────────────────────────────────┐
│  Your terminal                                                   │
│       │  ↑                                                       │
│       ↓  │                                                       │
│  ┌─────────────────────────────────────────┐                    │
│  │  auto-yes  PTY  proxy                   │                    │
│  │                                          │                    │
│  │  1. fork child on PTY slave             │                    │
│  │  2. select() on master + stdin          │                    │
│  │  3. expand ESC[nC → spaces             │                    │
│  │  4. strip ANSI, resolve \r\r\n         │                    │
│  │  5. scan last N lines with regex       │                    │
│  │  6. inject response via master fd      │                    │
│  │  7. forward SIGWINCH / SIGTERM         │                    │
│  └─────────────────────────────────────────┘                    │
│       │  ↑                                                       │
│       ↓  │                                                       │
│  Child process (claude / agent / aider / …)                     │
└──────────────────────────────────────────────────────────────────┘
```

**Anti-false-positive safeguards:**

| Guard | What it prevents |
|---|---|
| Typing suppress (1 s) | User's own keystrokes triggering auto-responses |
| Match cooldown (0.05 s) | Terminal redraws re-triggering the same prompt |
| Response cooldown (0.5 s default) | Rapid-fire duplicate responses |
| Bottom-up line scan | Matching stale text buried in scrollback |
| Buffer clear on input | Stale prompt text re-matching after user interaction |

---

## CLI reference

```
auto-yes <profile> [ARGS...]       wrap an AI CLI tool directly (recommended)
auto-yes --on [OPTIONS]            start an auto-yes shell session
auto-yes run [OPTIONS] -- CMD...   run a single command with auto-yes
auto-yes list, -l, --list          list all available CLI profiles
auto-yes patterns [CATEGORY...]    list prompt patterns (optionally filtered)
auto-yes add-pattern PATTERN       persist a custom regex pattern
auto-yes del-pattern PATTERN       remove a custom pattern
auto-yes status                    check if auto-yes is active in current shell
auto-yes ls                        list all running auto-yes sessions with PID
auto-yes pause <pid|all>           pause auto-responses for a session
auto-yes continue <pid|all>        resume auto-responses for a session
```

### Options (for `--on` and `run`)

| Flag | Description | Default |
|------|-------------|---------|
| `--auto` | Overnight mode: all profiles, 0.05s cooldown, verbose | off |
| `--response TEXT` | Text to send when a prompt is detected | `y` |
| `--cooldown FLOAT` | Seconds between auto-responses | `0.5` |
| `--delay FLOAT` | Seconds to wait before approving; press any key to cancel | `0` |
| `--heartbeat SECONDS` | Send Enter every N seconds of inactivity (keeps Claude/Cursor responsive) | `0` |
| `--verbose`, `-v` | Print a notice each time auto-yes responds | off |
| `--quiet`, `-q` | Suppress all auto-yes output (no banner, no notices) | off |
| `--pattern REGEX` | Extra prompt pattern (repeatable) | — |
| `--cli NAME` | AI CLI profile to load (repeatable, or `all`) | — |
| `--log FILE` | Write debug log (raw output, cleaned text, detections) | — |

---

## Supported tools & pattern categories

### AI CLI profiles

| Profile | Binary | Tool | Key prompt patterns |
|---------|--------|------|---------------------|
| `claude` | `claude` | **Anthropic Claude Code** | `❯ 1. Yes, I trust this folder`, `❯ Allow once`, `Do you want to proceed?` |
| `cursor` | `agent` | **Cursor Agent CLI** | `→ Run (once) (y)`, `→ Run (always) (a)`, `▶ [a] Trust this workspace` |
| `gemini` | `gemini` | Google Gemini CLI | `1. Allow once`, `2. Allow for this session`, `3. Always allow` |
| `codex` | `codex` | OpenAI Codex CLI | `1. Approve and run now`, `1. Yes, allow Codex to work` |
| `copilot` | `gh copilot` | GitHub Copilot CLI | `1. Yes, proceed`, `Allow Copilot to run` |
| `aider` | `aider` | Aider AI Coding | `(Y)es/(N)o`, `Run shell command?`, `Add … to the chat?` |
| `openhands` | `openhands` | OpenHands AI Agent | `Do you want to execute this action?`, `Approve` |
| `windsurf` | `windsurf` | Codeium Windsurf | `Accept changes?`, `Run this command?` |
| `qwen` | `qwen` | Alibaba Qwen Code | `1. Yes`, `Approve execution?` |
| `amazonq` | `q` | Amazon Q Developer | `Do you approve this action?`, `Accept suggestion?` |
| `grok` | `grok` | xAI Grok CLI | `1. Yes` |
| `auggie` | `auggie` | Augment Code CLI | `[Y] Enable indexing` |
| `amp` | `amp` | Sourcegraph Amp CLI | `Approve` |

### Generic patterns (opt-in via `--cli generic`)

| Type | Examples |
|------|----------|
| Bracket choices | `[y/n]`, `[Y/n]`, `(y/N)`, `[yes/no]`, `([y]/n)`, `(y)` |
| Styled choices | `[Y]es / [N]o`, bare `y/n:` |
| Question prompts | `Continue?`, `Proceed?`, `Are you sure?`, `Would you like to…?` |
| Safe action prompts | `Allow?`, `Approve?`, `Accept?`, `Download?`, `Enable?`, `Create?` |
| Agreement prompts | `Do you agree?`, `Accept the license`, `Agree to the terms` |
| SSH fingerprint | `continue connecting (yes/no/[fingerprint])?` → responds `yes` |
| Terraform | `Only 'yes' will be accepted` → responds `yes` |
| Full-word yes | `Type 'yes' to continue`, `Enter 'yes' to proceed` → responds `yes` |
| Press enter | `Press Enter to continue` → responds with empty string |
| Default value | `(default: Y)`, `[default=yes]` → accepts default with empty |
| **Excluded (dangerous)** | `Overwrite?`, `Delete?`, `Remove?`, `Upgrade?`, `Restart?`, `Reboot?` |

```bash
auto-yes patterns claude          # inspect Claude patterns
auto-yes patterns cursor gemini   # inspect multiple profiles
auto-yes patterns                 # list everything
```

### Custom patterns

```bash
# persist a custom pattern for all future sessions
auto-yes add-pattern 'accept license\?'

# one-off extra pattern for a single run
auto-yes run --pattern 'custom_prompt\?' -- ./my-script.sh
```

---

## Multi-agent & parallel agent scenarios

`auto-yes` is designed for **multi-agent orchestration** where multiple AI agents run concurrently and each may trigger prompts:

```bash
# 5 parallel Claude Code subagents — auto-yes handles all prompts
auto-yes run --auto -- orchestrator --agents 5 --task "migrate database schema"

# Overnight loop: run until complete, auto-approve every permission
while true; do
    auto-yes run --auto -- claude "continue where you left off"
    sleep 60
done
```

Tested with 5 simultaneous agents, 10-iteration overnight loops, interleaved Claude + Cursor prompts, and 1 000+ rapid sequential approvals.

---

## Platform support

| Platform | Method | Notes |
|----------|--------|-------|
| **Linux** | `pty` + `select` | Full PTY, zero external deps |
| **macOS** | `pty` + `select` | Full PTY, zero external deps |
| **Windows** | `pywinpty` | Install `auto-yes[windows]` |
| Windows (fallback) | `subprocess` pipes | Works without pywinpty |
| Rocky Linux / RHEL | `pty` + `select` | Tested on Rocky 9 |
| Ubuntu / Debian | `pty` + `select` | Tested on Ubuntu 22.04 / 24.04 |

---

## Comparison with `yes(1)`

| | `yes \| cmd` | `auto-yes run -- cmd` |
|---|---|---|
| Prompt detection | None — floods stdin blindly | Smart regex, bottom-up scan |
| User can still type | No | Yes, fully interactive |
| PTY (colors / progress bars) | Broken | Preserved |
| False-positive protection | None | Typing suppress + cooldown |
| AI-specific prompts | No | 13 AI tool profiles built-in |
| Custom patterns | No | Yes, persisted or one-off |
| Cross-platform | Unix only | Linux + macOS + Windows |

---

## Python API

```python
from auto_yes.runner import Runner
from auto_yes.patterns import get_command

# wrap claude with all its patterns
runner = Runner(
    categories=["claude"],
    cooldown=0.1,
    verbose=True,
)
exit_code = runner.run_command(["claude", "fix the tests"])

# generic patterns for any command
runner = Runner(categories=["generic"], response="y")
exit_code = runner.run_command(["apt", "install", "nginx"])

# custom extra pattern on top of a profile
runner = Runner(
    categories=["cursor"],
    extra_patterns=[r"deploy to production\?"],
)
cmd = get_command("cursor")   # → ["agent"]
exit_code = runner.run_command(cmd + ["chat", "deploy the app"])
```

---

## Configuration

Stored at `~/.config/auto-yes/config.json` (Linux / macOS) or
`%APPDATA%\auto-yes\config.json` (Windows):

```json
{
  "custom_patterns": [],
  "response": "y",
  "cooldown": 0.5,
  "verbose": false
}
```

---

## Adding a new AI CLI profile

Add one entry to `REGISTRY` in `src/auto_yes/patterns.py`:

```python
_MY_TOOL = {
    "description": "My AI Tool CLI",
    "command": ["my-tool"],              # real binary (list of strings)
    "patterns": [
        (r"approve action\?", None),     # None → use default response ("y")
        (r"type yes to confirm", "yes"), # explicit response string
    ],
}
REGISTRY["my-tool"] = _MY_TOOL
```

No other file needs to change. Run `auto-yes list` to verify it appears.

---

## Development

```bash
git clone https://github.com/host452b/auto-yes.git
cd auto-yes
pip install -e ".[dev]"

# run all 270 tests
pytest

# run only integration tests (real PTY scenarios)
pytest tests/scenarios/ -v

# run stress tests
pytest tests/test_stress.py -v

# lint + type check
ruff check src/ tests/
mypy src/auto_yes/
```

---

## License

[MIT](LICENSE) © auto-yes contributors
