osc7501 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- osc7501-1.0.0/.github/FUNDING.yml +4 -0
- osc7501-1.0.0/.github/workflows/publish.yml +64 -0
- osc7501-1.0.0/.github/workflows/test.yml +36 -0
- osc7501-1.0.0/.gitignore +11 -0
- osc7501-1.0.0/.python-version +1 -0
- osc7501-1.0.0/CHANGELOG.md +20 -0
- osc7501-1.0.0/CONTRIBUTING.md +142 -0
- osc7501-1.0.0/LICENSE +21 -0
- osc7501-1.0.0/PKG-INFO +173 -0
- osc7501-1.0.0/README.md +146 -0
- osc7501-1.0.0/osc7501/__init__.py +35 -0
- osc7501-1.0.0/osc7501/encode.py +118 -0
- osc7501-1.0.0/osc7501/py.typed +0 -0
- osc7501-1.0.0/osc7501/terminal.py +467 -0
- osc7501-1.0.0/pyproject.toml +53 -0
- osc7501-1.0.0/tests/test_detect.py +86 -0
- osc7501-1.0.0/tests/test_encode.py +119 -0
- osc7501-1.0.0/tests/test_terminal.py +134 -0
- osc7501-1.0.0/uv.lock +79 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout
|
|
15
|
+
uses: actions/checkout@v5
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v6
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.11"
|
|
21
|
+
|
|
22
|
+
- name: Build
|
|
23
|
+
run: uv build
|
|
24
|
+
|
|
25
|
+
- name: Upload distributions
|
|
26
|
+
uses: actions/upload-artifact@v4
|
|
27
|
+
with:
|
|
28
|
+
name: dist
|
|
29
|
+
path: dist/
|
|
30
|
+
|
|
31
|
+
publish:
|
|
32
|
+
needs: build
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
environment:
|
|
35
|
+
name: pypi
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write
|
|
38
|
+
contents: write
|
|
39
|
+
steps:
|
|
40
|
+
- name: Install uv
|
|
41
|
+
uses: astral-sh/setup-uv@v6
|
|
42
|
+
with:
|
|
43
|
+
python-version: "3.11"
|
|
44
|
+
|
|
45
|
+
- name: Download distributions
|
|
46
|
+
uses: actions/download-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: dist
|
|
49
|
+
path: dist/
|
|
50
|
+
|
|
51
|
+
- name: Generate PEP 740 attestations
|
|
52
|
+
uses: astral-sh/attest-action@f589a42a7efb6fe400b4f400de60b4bc90390027 # v0.0.6
|
|
53
|
+
|
|
54
|
+
- name: Publish
|
|
55
|
+
run: uv publish
|
|
56
|
+
|
|
57
|
+
- name: Create GitHub Release
|
|
58
|
+
uses: softprops/action-gh-release@v2
|
|
59
|
+
with:
|
|
60
|
+
tag_name: ${{ github.ref_name }}
|
|
61
|
+
name: Release ${{ github.ref_name }}
|
|
62
|
+
files: dist/*
|
|
63
|
+
env:
|
|
64
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest]
|
|
16
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
17
|
+
include:
|
|
18
|
+
- os: macos-latest
|
|
19
|
+
python-version: "3.14"
|
|
20
|
+
- os: windows-latest
|
|
21
|
+
python-version: "3.14"
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- name: Checkout
|
|
25
|
+
uses: actions/checkout@v5
|
|
26
|
+
|
|
27
|
+
- name: Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@v6
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python-version }}
|
|
31
|
+
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: uv sync --locked --dev
|
|
34
|
+
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: uv run pytest
|
osc7501-1.0.0/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `encode()` builds one OSC 7501 revision 0.4 report
|
|
13
|
+
- `idle()`, `working()`, `done()`, `blocked()`, `error()`, and `clear()` write that report to a terminal
|
|
14
|
+
- `working()` returns a `Job` that repeats `app`, `id`, and `title`, skips a repeated report, and writes `done`, `error`, or `idle` when a `with` block ends
|
|
15
|
+
- `detect()`, `query()`, and `parse_reply()` ask whether the terminal supports the protocol
|
|
16
|
+
- Control characters in `msg` and `title` are replaced before base64 encoding
|
|
17
|
+
- Zero runtime dependencies
|
|
18
|
+
- Python 3.11+
|
|
19
|
+
|
|
20
|
+
[1.0.0]: https://github.com/ysskrishna/osc7501/releases/tag/v1.0.0
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Contributing to osc7501
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to `osc7501`! This document provides guidelines and instructions for contributing.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- Python 3.11 or higher
|
|
10
|
+
- [uv](https://github.com/astral-sh/uv)
|
|
11
|
+
|
|
12
|
+
### Setting Up the Development Environment
|
|
13
|
+
|
|
14
|
+
1. **Clone the repository**:
|
|
15
|
+
```bash
|
|
16
|
+
git clone https://github.com/ysskrishna/osc7501.git
|
|
17
|
+
cd osc7501
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. **Install dependencies**:
|
|
21
|
+
```bash
|
|
22
|
+
uv sync --locked --dev
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. **Verify the setup**:
|
|
26
|
+
```bash
|
|
27
|
+
uv run pytest
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Development Workflow
|
|
31
|
+
|
|
32
|
+
### Running Tests
|
|
33
|
+
|
|
34
|
+
Run the test suite to ensure everything works:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv run pytest
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Run a specific test file:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
uv run pytest tests/test_encode.py
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Code Style
|
|
47
|
+
|
|
48
|
+
- Follow [PEP 8](https://pep8.org/) style guidelines
|
|
49
|
+
- Use type hints for all function parameters and return values
|
|
50
|
+
- Keep functions simple and focused
|
|
51
|
+
- Add docstrings to all public functions
|
|
52
|
+
|
|
53
|
+
### Changing a report
|
|
54
|
+
|
|
55
|
+
The byte format lives in `osc7501/encode.py`. Writing and `detect()` live in `osc7501/terminal.py`.
|
|
56
|
+
|
|
57
|
+
1. Add a failing test in `tests/` for the sequence or the error
|
|
58
|
+
2. Change the encoder or the writer
|
|
59
|
+
3. Run `uv run pytest`
|
|
60
|
+
4. Open a pull request into `main`
|
|
61
|
+
|
|
62
|
+
Do not probe the terminal from an emit path. `detect()` is opt-in because it reads input.
|
|
63
|
+
|
|
64
|
+
## Submitting Changes
|
|
65
|
+
|
|
66
|
+
### Pull Request Process
|
|
67
|
+
|
|
68
|
+
1. **Create a branch**:
|
|
69
|
+
```bash
|
|
70
|
+
git checkout -b feature/your-feature-name
|
|
71
|
+
# or
|
|
72
|
+
git checkout -b fix/your-fix-name
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
2. **Make your changes**:
|
|
76
|
+
- Write your code
|
|
77
|
+
- Add tests for new functionality
|
|
78
|
+
- Ensure all tests pass
|
|
79
|
+
- Update documentation if needed
|
|
80
|
+
|
|
81
|
+
3. **Commit your changes**:
|
|
82
|
+
```bash
|
|
83
|
+
git add .
|
|
84
|
+
git commit -m "Description of your changes"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Use clear, descriptive commit messages. Follow the format:
|
|
88
|
+
- `feat: add new feature`
|
|
89
|
+
- `fix: fix bug description`
|
|
90
|
+
- `docs: update documentation`
|
|
91
|
+
- `test: add tests for feature`
|
|
92
|
+
- `refactor: improve code structure`
|
|
93
|
+
|
|
94
|
+
4. **Push to your fork**:
|
|
95
|
+
```bash
|
|
96
|
+
git push origin feature/your-feature-name
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
5. **Create a Pull Request** into `main`:
|
|
100
|
+
- Go to the repository on GitHub
|
|
101
|
+
- Click "New Pull Request"
|
|
102
|
+
- Select your branch
|
|
103
|
+
- Fill out the PR description with:
|
|
104
|
+
- Description of changes
|
|
105
|
+
- Related issues (if any)
|
|
106
|
+
- Testing instructions
|
|
107
|
+
|
|
108
|
+
### Pull Request Guidelines
|
|
109
|
+
|
|
110
|
+
- Keep PRs focused on a single feature or fix
|
|
111
|
+
- Ensure all tests pass
|
|
112
|
+
- Update documentation if you're adding new features
|
|
113
|
+
- Write clear commit messages
|
|
114
|
+
- Reference any related issues
|
|
115
|
+
|
|
116
|
+
## Reporting Issues
|
|
117
|
+
|
|
118
|
+
When reporting issues, please include:
|
|
119
|
+
|
|
120
|
+
- Python version
|
|
121
|
+
- Package version
|
|
122
|
+
- Operating system and version
|
|
123
|
+
- Steps to reproduce
|
|
124
|
+
- Expected behavior
|
|
125
|
+
- Actual behavior
|
|
126
|
+
- Any relevant error messages or stack traces
|
|
127
|
+
|
|
128
|
+
## Code of Conduct
|
|
129
|
+
|
|
130
|
+
- Be respectful and considerate
|
|
131
|
+
- Welcome newcomers and help them learn
|
|
132
|
+
- Focus on constructive feedback
|
|
133
|
+
- Be open to feedback and suggestions
|
|
134
|
+
|
|
135
|
+
## Questions?
|
|
136
|
+
|
|
137
|
+
If you have questions about contributing, feel free to:
|
|
138
|
+
|
|
139
|
+
- Open an issue on GitHub
|
|
140
|
+
- Check existing issues and discussions
|
|
141
|
+
|
|
142
|
+
Thank you for contributing to `osc7501`!
|
osc7501-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Y. Siva Sai Krishna
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
osc7501-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: osc7501
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Report terminal program status with OSC 7501.
|
|
5
|
+
Project-URL: Homepage, https://github.com/ysskrishna/osc7501
|
|
6
|
+
Project-URL: Repository, https://github.com/ysskrishna/osc7501.git
|
|
7
|
+
Project-URL: Issues, https://github.com/ysskrishna/osc7501/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/ysskrishna/osc7501/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: "Y. Siva Sai Krishna" <sivasaikrishnassk@gmail.com>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cli,osc,osc7501,status,terminal
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Topic :: Terminals
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# OSC 7501
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
[](https://www.python.org/downloads/)
|
|
32
|
+
[](https://github.com/ysskrishna/osc7501/blob/main/LICENSE)
|
|
33
|
+

|
|
34
|
+
[](https://pypi.org/project/osc7501/)
|
|
35
|
+
[](https://pepy.tech/projects/osc7501)
|
|
36
|
+
|
|
37
|
+
Report terminal program status with OSC 7501. Inspired by the [osc-status](https://github.com/jonahsnider/osc-status) npm package.
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- **States**: `idle`, `working`, `done`, `blocked`, `error`, and `clear`
|
|
42
|
+
- **One job**: a context manager that repeats `app`, `id`, and `title` and closes the job for you
|
|
43
|
+
- **Safe text**: control characters become spaces before base64, so one newline cannot drop the report
|
|
44
|
+
- **Optional probe**: ask the terminal whether it implements revision 0.4
|
|
45
|
+
- **Zero dependencies**: the library only uses the Python standard library
|
|
46
|
+
- **TTY gate**: reports are skipped when stderr is a pipe, unless you pass `enabled=True`
|
|
47
|
+
|
|
48
|
+
## Why OSC 7501?
|
|
49
|
+
|
|
50
|
+
OSC 9;4 progress can say that a program is busy, at a percentage, or failed. It has no message and no way to say the program is waiting on the user. A window title is one free-form string.
|
|
51
|
+
|
|
52
|
+
OSC 7501 adds a state, a reason (`permission`, `question`, or `auth`), and a stable `app` name. The terminal decides how to show that. A terminal that does not know the sequence ignores it, so sending a report is safe.
|
|
53
|
+
|
|
54
|
+
Spec: [Program Status Protocol, revision 0.4](https://control-codes.page/proposals/osc-7501/) (2026-10-10).
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install osc7501
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage Examples
|
|
63
|
+
|
|
64
|
+
### Helpers
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from osc7501 import blocked, done, working
|
|
68
|
+
|
|
69
|
+
working(progress=40, msg="Building docs")
|
|
70
|
+
blocked(kind="permission", msg="Approve deploy?")
|
|
71
|
+
done(msg="Docs built")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Each report replaces the terminal's record. Repeat every field you still want. `clear()` with no `id` removes every record in the terminal.
|
|
75
|
+
|
|
76
|
+
Reports go to stderr, and only when it is a terminal.
|
|
77
|
+
|
|
78
|
+
### One job
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from osc7501 import working
|
|
82
|
+
|
|
83
|
+
with working(app="make", msg="Building docs") as job:
|
|
84
|
+
job.blocked(kind="question", msg="Overwrite config.toml?")
|
|
85
|
+
job.done(msg="Docs built")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Enter writes `working`. A clean exit writes `done` with no message. An exception writes `error`. `KeyboardInterrupt` writes `idle`. If you already called `job.done()` or `job.error()`, the exit writes nothing.
|
|
89
|
+
|
|
90
|
+
`msg` for `kind="auth"` is the prompt, never the secret.
|
|
91
|
+
|
|
92
|
+
### Detection
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from osc7501 import detect
|
|
96
|
+
|
|
97
|
+
print(detect().result)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Call `detect()` before reading input. It can consume keystrokes typed during the wait. On Windows, or when `/dev/tty` cannot be opened, the result is `Detection.UNKNOWN`. Helpers never probe on their own.
|
|
101
|
+
|
|
102
|
+
## Where reports show up
|
|
103
|
+
|
|
104
|
+
This list is from the [awesome-osc7501 matrix](https://github.com/hyeebeen/awesome-osc7501) dated 2026-10-11. It was not re-checked for this release.
|
|
105
|
+
|
|
106
|
+
Shows reports: Rex, TUIOS, termio, SwiftTerm, Termy, con-terminal, phux, thurm, wietty, Prowl.
|
|
107
|
+
|
|
108
|
+
Ignores reports: the Ghostty app (libghostty parses them; the app does not opt in), tmux (drops them unless DCS passthrough and `allow-passthrough` are on; this release does not wrap them), Kitty, WezTerm, Alacritty, iTerm2, Windows Terminal, VS Code, Zed, Warp, zellij.
|
|
109
|
+
|
|
110
|
+
## API Reference
|
|
111
|
+
|
|
112
|
+
| Name | Description |
|
|
113
|
+
|------|-------------|
|
|
114
|
+
| `encode(state, *, msg, title, app, id, kind, progress) -> str` | Build one sequence. Does not write. |
|
|
115
|
+
| `working(*, msg, title, app, id, progress, stream, enabled) -> Job` | Write `working` and return a `Job`. |
|
|
116
|
+
| `Job.update(*, progress, msg) -> bool` | Write another `working` report. Skips a byte-identical repeat. |
|
|
117
|
+
| `Job.blocked(*, kind, msg, progress) -> bool` | Write `blocked`, repeating `app`, `id`, and `title`. |
|
|
118
|
+
| `Job.done(*, msg) -> bool` / `Job.error` / `Job.idle` | Write that state. |
|
|
119
|
+
| `idle`, `done`, `error`, `blocked`, `clear` | Write one report. Return `True` only when bytes were written. |
|
|
120
|
+
| `query() -> str` | The `OSC 7501 ; ? ST` query. |
|
|
121
|
+
| `parse_reply(sequence) -> Support \| None` | Parse one reply. Missing lists mean the five states and three kinds. |
|
|
122
|
+
| `detect(*, timeout=0.2) -> Support` | Probe `/dev/tty`. `Support.supported` is true only for `Detection.SUPPORTED`. |
|
|
123
|
+
| `State`, `Kind` | `StrEnum` values. Plain strings are accepted too. |
|
|
124
|
+
|
|
125
|
+
## Learn More
|
|
126
|
+
|
|
127
|
+
- [Program Status Protocol (OSC 7501)](https://control-codes.page/proposals/osc-7501/)
|
|
128
|
+
- [Mitchell Hashimoto: A Terminal Protocol for Program Status](https://mitchellh.com/writing/program-status-osc7501)
|
|
129
|
+
- [awesome-osc7501](https://github.com/hyeebeen/awesome-osc7501)
|
|
130
|
+
|
|
131
|
+
## Acknowledgments
|
|
132
|
+
|
|
133
|
+
- [Mitchell Hashimoto](https://github.com/mitchellh), for the specification
|
|
134
|
+
- [Jonah Snider](https://github.com/jonahsnider), for [osc-status](https://github.com/jonahsnider/osc-status)
|
|
135
|
+
- [Adam Duke](https://github.com/adamvduke), for [pst](https://github.com/adamvduke/pst)
|
|
136
|
+
|
|
137
|
+
## Built and maintained by
|
|
138
|
+
|
|
139
|
+
osc7501 is built and maintained by:
|
|
140
|
+
|
|
141
|
+
| | Name | GitHub | Role |
|
|
142
|
+
|---|------|--------|------|
|
|
143
|
+
| <img src="https://github.com/ysskrishna.png?size=120" width="60" height="60" alt="Y. Siva Sai Krishna"> | **Y. Siva Sai Krishna** | [@ysskrishna](https://github.com/ysskrishna) | Creator |
|
|
144
|
+
|
|
145
|
+
## Changelog
|
|
146
|
+
|
|
147
|
+
See [CHANGELOG.md](https://github.com/ysskrishna/osc7501/blob/main/CHANGELOG.md) for a detailed list of changes and version history.
|
|
148
|
+
|
|
149
|
+
## Contributing
|
|
150
|
+
|
|
151
|
+
We welcome contributions! Please see our [Contributing Guide](https://github.com/ysskrishna/osc7501/blob/main/CONTRIBUTING.md) for details.
|
|
152
|
+
|
|
153
|
+
## Support
|
|
154
|
+
|
|
155
|
+
If you find this library helpful:
|
|
156
|
+
|
|
157
|
+
- ⭐ Star the repository
|
|
158
|
+
- 🐛 Report issues
|
|
159
|
+
- 🔀 Submit pull requests
|
|
160
|
+
- 💝 [Sponsor on GitHub](https://github.com/sponsors/ysskrishna)
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
MIT © [Y. Siva Sai Krishna](https://github.com/ysskrishna) - see [LICENSE](https://github.com/ysskrishna/osc7501/blob/main/LICENSE) file for details.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
<p align="left">
|
|
169
|
+
<a href="https://github.com/ysskrishna">Author's GitHub</a> •
|
|
170
|
+
<a href="https://linkedin.com/in/ysskrishna">Author's LinkedIn</a> •
|
|
171
|
+
<a href="https://github.com/ysskrishna/osc7501/issues">Report Issues</a> •
|
|
172
|
+
<a href="https://pypi.org/project/osc7501/">Package on PyPI</a>
|
|
173
|
+
</p>
|
osc7501-1.0.0/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# OSC 7501
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://github.com/ysskrishna/osc7501/blob/main/LICENSE)
|
|
6
|
+

|
|
7
|
+
[](https://pypi.org/project/osc7501/)
|
|
8
|
+
[](https://pepy.tech/projects/osc7501)
|
|
9
|
+
|
|
10
|
+
Report terminal program status with OSC 7501. Inspired by the [osc-status](https://github.com/jonahsnider/osc-status) npm package.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **States**: `idle`, `working`, `done`, `blocked`, `error`, and `clear`
|
|
15
|
+
- **One job**: a context manager that repeats `app`, `id`, and `title` and closes the job for you
|
|
16
|
+
- **Safe text**: control characters become spaces before base64, so one newline cannot drop the report
|
|
17
|
+
- **Optional probe**: ask the terminal whether it implements revision 0.4
|
|
18
|
+
- **Zero dependencies**: the library only uses the Python standard library
|
|
19
|
+
- **TTY gate**: reports are skipped when stderr is a pipe, unless you pass `enabled=True`
|
|
20
|
+
|
|
21
|
+
## Why OSC 7501?
|
|
22
|
+
|
|
23
|
+
OSC 9;4 progress can say that a program is busy, at a percentage, or failed. It has no message and no way to say the program is waiting on the user. A window title is one free-form string.
|
|
24
|
+
|
|
25
|
+
OSC 7501 adds a state, a reason (`permission`, `question`, or `auth`), and a stable `app` name. The terminal decides how to show that. A terminal that does not know the sequence ignores it, so sending a report is safe.
|
|
26
|
+
|
|
27
|
+
Spec: [Program Status Protocol, revision 0.4](https://control-codes.page/proposals/osc-7501/) (2026-10-10).
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install osc7501
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage Examples
|
|
36
|
+
|
|
37
|
+
### Helpers
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from osc7501 import blocked, done, working
|
|
41
|
+
|
|
42
|
+
working(progress=40, msg="Building docs")
|
|
43
|
+
blocked(kind="permission", msg="Approve deploy?")
|
|
44
|
+
done(msg="Docs built")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Each report replaces the terminal's record. Repeat every field you still want. `clear()` with no `id` removes every record in the terminal.
|
|
48
|
+
|
|
49
|
+
Reports go to stderr, and only when it is a terminal.
|
|
50
|
+
|
|
51
|
+
### One job
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from osc7501 import working
|
|
55
|
+
|
|
56
|
+
with working(app="make", msg="Building docs") as job:
|
|
57
|
+
job.blocked(kind="question", msg="Overwrite config.toml?")
|
|
58
|
+
job.done(msg="Docs built")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Enter writes `working`. A clean exit writes `done` with no message. An exception writes `error`. `KeyboardInterrupt` writes `idle`. If you already called `job.done()` or `job.error()`, the exit writes nothing.
|
|
62
|
+
|
|
63
|
+
`msg` for `kind="auth"` is the prompt, never the secret.
|
|
64
|
+
|
|
65
|
+
### Detection
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from osc7501 import detect
|
|
69
|
+
|
|
70
|
+
print(detect().result)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Call `detect()` before reading input. It can consume keystrokes typed during the wait. On Windows, or when `/dev/tty` cannot be opened, the result is `Detection.UNKNOWN`. Helpers never probe on their own.
|
|
74
|
+
|
|
75
|
+
## Where reports show up
|
|
76
|
+
|
|
77
|
+
This list is from the [awesome-osc7501 matrix](https://github.com/hyeebeen/awesome-osc7501) dated 2026-10-11. It was not re-checked for this release.
|
|
78
|
+
|
|
79
|
+
Shows reports: Rex, TUIOS, termio, SwiftTerm, Termy, con-terminal, phux, thurm, wietty, Prowl.
|
|
80
|
+
|
|
81
|
+
Ignores reports: the Ghostty app (libghostty parses them; the app does not opt in), tmux (drops them unless DCS passthrough and `allow-passthrough` are on; this release does not wrap them), Kitty, WezTerm, Alacritty, iTerm2, Windows Terminal, VS Code, Zed, Warp, zellij.
|
|
82
|
+
|
|
83
|
+
## API Reference
|
|
84
|
+
|
|
85
|
+
| Name | Description |
|
|
86
|
+
|------|-------------|
|
|
87
|
+
| `encode(state, *, msg, title, app, id, kind, progress) -> str` | Build one sequence. Does not write. |
|
|
88
|
+
| `working(*, msg, title, app, id, progress, stream, enabled) -> Job` | Write `working` and return a `Job`. |
|
|
89
|
+
| `Job.update(*, progress, msg) -> bool` | Write another `working` report. Skips a byte-identical repeat. |
|
|
90
|
+
| `Job.blocked(*, kind, msg, progress) -> bool` | Write `blocked`, repeating `app`, `id`, and `title`. |
|
|
91
|
+
| `Job.done(*, msg) -> bool` / `Job.error` / `Job.idle` | Write that state. |
|
|
92
|
+
| `idle`, `done`, `error`, `blocked`, `clear` | Write one report. Return `True` only when bytes were written. |
|
|
93
|
+
| `query() -> str` | The `OSC 7501 ; ? ST` query. |
|
|
94
|
+
| `parse_reply(sequence) -> Support \| None` | Parse one reply. Missing lists mean the five states and three kinds. |
|
|
95
|
+
| `detect(*, timeout=0.2) -> Support` | Probe `/dev/tty`. `Support.supported` is true only for `Detection.SUPPORTED`. |
|
|
96
|
+
| `State`, `Kind` | `StrEnum` values. Plain strings are accepted too. |
|
|
97
|
+
|
|
98
|
+
## Learn More
|
|
99
|
+
|
|
100
|
+
- [Program Status Protocol (OSC 7501)](https://control-codes.page/proposals/osc-7501/)
|
|
101
|
+
- [Mitchell Hashimoto: A Terminal Protocol for Program Status](https://mitchellh.com/writing/program-status-osc7501)
|
|
102
|
+
- [awesome-osc7501](https://github.com/hyeebeen/awesome-osc7501)
|
|
103
|
+
|
|
104
|
+
## Acknowledgments
|
|
105
|
+
|
|
106
|
+
- [Mitchell Hashimoto](https://github.com/mitchellh), for the specification
|
|
107
|
+
- [Jonah Snider](https://github.com/jonahsnider), for [osc-status](https://github.com/jonahsnider/osc-status)
|
|
108
|
+
- [Adam Duke](https://github.com/adamvduke), for [pst](https://github.com/adamvduke/pst)
|
|
109
|
+
|
|
110
|
+
## Built and maintained by
|
|
111
|
+
|
|
112
|
+
osc7501 is built and maintained by:
|
|
113
|
+
|
|
114
|
+
| | Name | GitHub | Role |
|
|
115
|
+
|---|------|--------|------|
|
|
116
|
+
| <img src="https://github.com/ysskrishna.png?size=120" width="60" height="60" alt="Y. Siva Sai Krishna"> | **Y. Siva Sai Krishna** | [@ysskrishna](https://github.com/ysskrishna) | Creator |
|
|
117
|
+
|
|
118
|
+
## Changelog
|
|
119
|
+
|
|
120
|
+
See [CHANGELOG.md](https://github.com/ysskrishna/osc7501/blob/main/CHANGELOG.md) for a detailed list of changes and version history.
|
|
121
|
+
|
|
122
|
+
## Contributing
|
|
123
|
+
|
|
124
|
+
We welcome contributions! Please see our [Contributing Guide](https://github.com/ysskrishna/osc7501/blob/main/CONTRIBUTING.md) for details.
|
|
125
|
+
|
|
126
|
+
## Support
|
|
127
|
+
|
|
128
|
+
If you find this library helpful:
|
|
129
|
+
|
|
130
|
+
- ⭐ Star the repository
|
|
131
|
+
- 🐛 Report issues
|
|
132
|
+
- 🔀 Submit pull requests
|
|
133
|
+
- 💝 [Sponsor on GitHub](https://github.com/sponsors/ysskrishna)
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT © [Y. Siva Sai Krishna](https://github.com/ysskrishna) - see [LICENSE](https://github.com/ysskrishna/osc7501/blob/main/LICENSE) file for details.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
<p align="left">
|
|
142
|
+
<a href="https://github.com/ysskrishna">Author's GitHub</a> •
|
|
143
|
+
<a href="https://linkedin.com/in/ysskrishna">Author's LinkedIn</a> •
|
|
144
|
+
<a href="https://github.com/ysskrishna/osc7501/issues">Report Issues</a> •
|
|
145
|
+
<a href="https://pypi.org/project/osc7501/">Package on PyPI</a>
|
|
146
|
+
</p>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Report terminal program status with OSC 7501."""
|
|
2
|
+
|
|
3
|
+
from osc7501.encode import Kind, State, encode
|
|
4
|
+
from osc7501.terminal import (
|
|
5
|
+
Detection,
|
|
6
|
+
Job,
|
|
7
|
+
Support,
|
|
8
|
+
blocked,
|
|
9
|
+
clear,
|
|
10
|
+
detect,
|
|
11
|
+
done,
|
|
12
|
+
error,
|
|
13
|
+
idle,
|
|
14
|
+
parse_reply,
|
|
15
|
+
query,
|
|
16
|
+
working,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"Detection",
|
|
21
|
+
"Job",
|
|
22
|
+
"Kind",
|
|
23
|
+
"State",
|
|
24
|
+
"Support",
|
|
25
|
+
"blocked",
|
|
26
|
+
"clear",
|
|
27
|
+
"detect",
|
|
28
|
+
"done",
|
|
29
|
+
"encode",
|
|
30
|
+
"error",
|
|
31
|
+
"idle",
|
|
32
|
+
"parse_reply",
|
|
33
|
+
"query",
|
|
34
|
+
"working",
|
|
35
|
+
]
|