Metadata-Version: 2.4
Name: sengptr
Version: 0.2.2
Summary: Sengptr (Sengpt Revive), a maintained terminal client for ChatGPT
License-Expression: GPL-3.0-only
License-File: LICENSE
Keywords: chatgpt,gpt,cli,command line,terminal,free gpt,free,no api key,no api,openai,openai chatgpt,chatgpt free
Author: SenZmaKi
Author-email: senzmaki@gmail.com
Requires-Python: >=3.11,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Requires-Dist: appdirs (>=1.4.4,<2)
Requires-Dist: playwright (>=1.55,<2)
Requires-Dist: pyperclip (>=1.8.2,<2)
Project-URL: Bug Tracker, https://github.com/llegaspo/sengpt-R/issues
Project-URL: Homepage, https://github.com/llegaspo/sengpt-R
Project-URL: Repository, https://github.com/llegaspo/sengpt-R
Description-Content-Type: text/markdown

# Sengptr

> Sengptr (Sengpt Revive) is a maintained fork that lets you use your ChatGPT
> web account from the terminal—no API key required.

This project continues the previously archived Sengpt CLI with a browser-based
integration that works with the current ChatGPT website. It runs ChatGPT in a
dedicated Chromium profile, letting you ask a one-off question, keep an
interactive conversation going, or pipe a file straight into a prompt without
leaving your terminal.

![Sengptr terminal demo](.github/assets/demo.gif)

> [!IMPORTANT]
> Sengptr is an independent, unofficial project. It automates the ChatGPT website,
> so changes to the site may occasionally require an update. Your normal account
> limits still apply, and you should only use an account you are authorized to
> access.

## What it can do

- Run one-off prompts or interactive conversations
- Accept piped input from files and other commands
- Keep a conversation so you can return to it later
- Copy responses to your clipboard or render Markdown with
  [Glow](https://github.com/charmbracelet/glow)
- Save generated files and images, and forward each real image preview exposed
  by ChatGPT while it is being generated
- Reuse prompts from a small local configuration file
- Keep your ChatGPT password and session data inside a local browser profile

## Requirements

- Python 3.11 or newer
- A ChatGPT account
- A graphical desktop for the initial sign-in
- [Xvfb](https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml) on
  Linux for invisible browser sessions
- Glow, optionally, for richer Markdown output in the terminal

Sengptr uses a real browser rather than ChatGPT's private web endpoints. If you
are building an application or do not specifically need access through your web
account, use the [official OpenAI API](https://developers.openai.com/api/docs/quickstart)
instead.

## Installation

Clone the repository and install it in a virtual environment:

```bash
git clone https://github.com/llegaspo/sengpt-R.git Sengptr
cd Sengptr
python -m venv .venv
source .venv/bin/activate
pip install -e .
playwright install chromium
```

After version `0.2.2` is published to PyPI, applications can install the
library with `python -m pip install 'sengptr>=0.2.2,<0.3.0'` instead of cloning
the repository. Install Playwright Chromium in the same environment.

### Upgrading from Sengpt

The package, Python module, and executable are now named `sengptr`. Reinstall
the project, then use `sengptr` in place of the old command.

On first run, Sengptr moves the previous default config directory—including its
saved browser profile—to the new Sengptr location. It refuses to merge when
both directories already exist, so neither profile is overwritten. During the
transition, `SENGPT_CONFIG_DIR` is accepted with a warning; replace it with
`SENGPTR_CONFIG_DIR`. The browser overrides are now `SENGPTR_XVFB_PATH` and
`SENGPTR_DEBUG`; their previous names are also accepted with a transition
warning.

On Windows, activate the environment with `.venv\Scripts\activate`.
Windows and macOS run a visible Chromium window by default. Invisible browser
sessions currently require Linux and Xvfb; `--headless` is unsupported on
Windows and macOS.

For invisible browser sessions on Linux, install Xvfb as well:

```bash
# Debian / Ubuntu
sudo apt install xvfb

# Arch Linux
sudo pacman -S xorg-server-xvfb
```

## First-time sign-in

Run:

```bash
sengptr --login
```

A Chromium window will open on ChatGPT. Complete the normal sign-in flow,
including SSO or two-factor authentication if needed. Sengptr closes the window
once the prompt composer is ready.

The login is stored in a dedicated browser profile outside the repository.
Treat that directory like any other signed-in browser profile: do not share or
commit it. You can see its location with `sengptr --config_file`.

## Usage

Start an interactive conversation:

```bash
sengptr
```

Start with a prompt and continue chatting:

```bash
sengptr "Explain the actor model"
```

The first answer streams into the terminal by default while ChatGPT is generating
it; Sengptr then waits for another prompt. On Linux, this works with the default
invisible browser mode. At the interactive prompt, type ordinary text without
shell quotes; apostrophes in the prompt are accepted.

Ask one question and exit:

```bash
sengptr --query "Summarize the CAP theorem"
```

While ChatGPT is responding in a terminal, Sengptr shows a live, replaceable text
preview by default, including when the browser runs invisibly on Linux.
The preview is cleared when generation finishes, then the final Markdown is
printed once. Redirected output still receives only the completed response.

Pipe content into a prompt:

```bash
cat README.md | sengptr --query "Point out anything unclear"
```

Attach a local file through ChatGPT's upload control:

```bash
sengptr --query --file report.pdf "Summarize this file"
sengptr --query --file report.pdf
```

`--file` also works for an initial interactive message or a later interactive
turn. Piped input remains prompt text; `--file` sends the file itself.

By default, one-off query conversations are removed from your ChatGPT history.
Use `--save` to keep one, then return to it later with:

```bash
sengptr --recent_conversation
```

Useful options include:

| Option | Purpose |
| --- | --- |
| `--login` | Open a browser and refresh the saved login |
| `--query` | Print one response and exit |
| `--save` | Keep a query in ChatGPT history |
| `--recent_conversation` | Continue the most recently saved conversation |
| `--model NAME` | Request a ChatGPT web model slug |
| `--effort LEVEL` | Choose `instant`, `medium`, `high`, or `extra-high` thinking |
| `--output DIRECTORY` | Save generated files and images in this directory |
| `--image-output DIRECTORY` | Legacy alias for `--output` |
| `--no_inline_images` | Disable inline previews in compatible terminals |
| `--headed` | Show Chromium (the default on Windows and macOS) |
| `--headless` | Hide Chromium with Xvfb on Linux (the Linux default) |
| `--copy` | Copy the final response to the clipboard |
| `--paste` | Add the clipboard contents to the prompt |
| `--file PATH` | Attach a local file to the message |
| `--no_glow` | Print Markdown without Glow |
| `--delete` | Delete an interactive conversation when it ends |

Run `sengptr --help` for the complete list.
Use `--` before a prompt that starts with a dash, for example
`sengptr --query -- "-3 is a negative number"`.

## Configuration

`sengptr --config_file` prints the path to `config.json` and the browser profile.
Every setting is optional:

```json
{
  "username": "You",
  "model": "",
  "effort": "",
  "default_mode": "interactive",
  "timeout_minutes": 45,
  "output_dir": ".",
  "no_glow": false,
  "copy": false,
  "save": false,
  "delete": false,
  "preconfigured_prompts": {
    "readme": "Write a concise README for the supplied code.",
    "explain": "Explain the supplied material clearly."
  }
}
```

If `headless` is omitted, it defaults to `true` on Linux and `false` on
Windows and macOS. Set it to `false` on Linux to show Chromium. Invisible
sessions are supported only on Linux with Xvfb.

Configured prompts become flags. For example:

```bash
cat app.py | sengptr --query --explain
```

Leave `model` empty to use your account's default. Available model names are
controlled by ChatGPT and may change over time. Leave `effort` empty to keep
ChatGPT's current setting. Override model and effort per launch with
`sengptr --model MODEL_SLUG --effort high "Compare these designs"`. Thinking
levels are selected through ChatGPT's model picker, so the level must be
available for the selected model and your account/workspace. `--model` passes
its value to a ChatGPT web URL; ChatGPT may ignore an API model ID such as
`gpt-5.6-sol`. Check the selected model in the browser before relying on it.

## Generated files and images

Files that ChatGPT exposes as downloads, including CSV, HTML, and ZIP files,
are saved in `output_dir` (the current working directory by default). Override
it for one command with `--output DIRECTORY`. The CLI prints each saved path;
the Python library emits a `GeneratedFile` event with the filename, MIME type,
and bytes. Existing `image_output_dir` and `--image-output` settings still work
as fallbacks. An explicit `--output` takes precedence over `--image-output` in
the same prompt.

Generated images use the same output directory. While ChatGPT is generating,
Sengptr atomically updates a
temporary preview file whenever the rendered image changes. The temporary file
is replaced by the final image at its original source quality when ChatGPT makes
that source available.

Kitty, Ghostty, and WezTerm can display the changing preview directly in the
terminal through the Kitty graphics protocol. Other terminals receive the path
to the changing preview on stderr and the final saved path on stdout. Redirected
stdout never receives terminal control sequences. Use `--no_inline_images` to
disable inline rendering explicitly.

Sengptr only forwards visual states that the ChatGPT webpage actually renders.
If a model or a future version of the webpage exposes no intermediate image,
Sengptr returns the final image without fabricating previews.

## Python library

Applications can use the same streaming browser integration directly from
Python. Create a login once with `sengptr --login`, then use the profile path
printed by `sengptr --config_file`:

```python
import asyncio
from sengptr import GeneratedFile, ImageSnapshot, ResponseCompleted, SengptrClient, TextSnapshot


async def main():
    async with SengptrClient("/path/to/sengptr/browser-profile") as client:
        conversation = client.new_conversation(model="")
        async for event in conversation.stream("Explain machine learning"):
            if isinstance(event, TextSnapshot):
                print(event.content, end="\r", flush=True)
            elif isinstance(event, ImageSnapshot):
                print(f"Image update {event.sequence}: {len(event.content)} bytes")
            elif isinstance(event, GeneratedFile):
                print(f"File {event.filename}: {len(event.content)} bytes")
            elif isinstance(event, ResponseCompleted):
                print(f"\nConversation: {event.conversation_id}")


asyncio.run(main())
```

Pass `file="/path/to/report.pdf"` to `conversation.stream()` to attach a local
file alongside the prompt. The prompt may be an empty string for a file-only
message. Upload availability and accepted file types depend on the signed-in
ChatGPT account and its current webpage.

`SengptrClient` is an async context manager; always close it (normally by using
`async with`) so Chromium and any Xvfb process are cleaned up. `conversation.stream()` yields
typed snapshots and a completion event; image bytes are available directly in
Python. Use one conversation operation at a time per client. If you stop
consuming a response early, close the stream with `contextlib.aclosing`, then
close the client and open a new one before sending another prompt. This is still
browser automation of the ChatGPT website, not an OpenAI API client, and the
profile must not be used by another Sengptr process at the same time.

For Node.js and other runtimes, see the separate
[sengptr-worker project](https://github.com/llegaspo/sengptr-worker), which exposes the same
events over a JSON Lines subprocess protocol.

The [library plan](docs/library-plan.md) tracks the remaining release checks,
including clean-environment installs and a real signed-in browser smoke test.

## Troubleshooting

**Chromium is missing**

```bash
playwright install chromium
```

**The prompt box never appears**

Run `sengptr --login` again and finish any sign-in or browser challenge in the
window that opens.

**The browser profile is already in use**

Close any other Chromium window started by Sengptr. A persistent profile can
only be used by one browser process at a time.

**An invisible session is blocked by a browser challenge**

Run `sengptr --headed` once, complete the challenge, and try again. On Linux,
normal invisible sessions use a full Chromium browser inside Xvfb rather than
Chromium's headless mode.

## How it works

The original Sengpt client called private ChatGPT endpoints with a copied
session cookie. That approach no longer works reliably and exposes session
credentials unnecessarily. This version keeps authentication in Chromium and
enters prompts through the ChatGPT interface. It observes text and generated
image updates in the rendered assistant turn, forwards previews as they appear,
and obtains the final response after the turn completes.

Because this integration depends on the rendered interface, ChatGPT UI changes
can break selectors. If that happens, please open an issue with the command you
ran and the error message you received—without including cookies or profile
data.

## Development

```bash
pip install -e . pytest
pytest
```

The regular test suite does not contact ChatGPT. The live browser smoke test is
opt-in so development and CI runs do not consume account quota.

To verify progressive images explicitly, provide both an authenticated profile
and a prompt. This test consumes one image generation and deletes its temporary
conversation afterward:

```bash
SENGPTR_LIVE_PROFILE=/path/to/browser-profile \
SENGPTR_LIVE_IMAGE_PROMPT="Generate a simple red circle on white." \
pytest tests/test_live_browser.py -k live_image
```

To verify generated-file downloads with a signed-in profile, use a prompt that
asks ChatGPT to attach a small file. This test deletes its conversation afterward:

```bash
SENGPTR_LIVE_PROFILE=/path/to/browser-profile \
SENGPTR_LIVE_FILE_PROMPT="Create and attach a CSV file with one data row." \
pytest tests/test_live_browser.py -k live_generated_file
```

To verify uploading a local file, use a signed-in profile and opt in to one
ChatGPT response. The test copies the profile, creates a temporary text file,
checks that ChatGPT read its contents, and deletes the test conversation:

```bash
SENGPTR_LIVE_PROFILE=/path/to/browser-profile \
SENGPTR_LIVE_UPLOAD=1 \
pytest tests/test_live_browser.py -k live_file_upload
```

To verify incremental text snapshots with an explicit quota-consuming prompt:

```bash
SENGPTR_LIVE_PROFILE=/path/to/browser-profile \
SENGPTR_LIVE_TEXT_PROMPT="Explain machine learning in at least five paragraphs." \
pytest tests/test_live_browser.py -k live_text
```

## License

Sengptr is available under the [GNU GPLv3](LICENSE), matching the original
project.

