dev-null-tty 0.1.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.
- dev_null_tty-0.1.0/PKG-INFO +99 -0
- dev_null_tty-0.1.0/README.md +89 -0
- dev_null_tty-0.1.0/pyproject.toml +24 -0
- dev_null_tty-0.1.0/pyproject.toml.orig +25 -0
- dev_null_tty-0.1.0/src/dev_null_tty/__init__.py +758 -0
- dev_null_tty-0.1.0/src/dev_null_tty/__main__.py +5 -0
- dev_null_tty-0.1.0/src/dev_null_tty/api.py +532 -0
- dev_null_tty-0.1.0/src/dev_null_tty/desktop.py +157 -0
- dev_null_tty-0.1.0/src/dev_null_tty/styles.tcss +185 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: dev-null-tty
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A terminal interface for /dev/null
|
|
5
|
+
Author: Avetis Avo Pisikyan
|
|
6
|
+
Author-email: Avetis Avo Pisikyan <apisikya@gmail.com>
|
|
7
|
+
Requires-Dist: textual>=8.2.8
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# dev-null-tty
|
|
12
|
+
|
|
13
|
+
A keyboard-first terminal client for [/dev/null](https://dev-null.sh), built
|
|
14
|
+
with [Textual](https://textual.textualize.io/) and managed with
|
|
15
|
+
[uv](https://docs.astral.sh/uv/).
|
|
16
|
+
|
|
17
|
+
The **Following**, **Latest**, and **Trending** journals load real commits from
|
|
18
|
+
the signed `/api/v1/log/{log}` endpoint after sign-in. Each journal supports
|
|
19
|
+
automatic cursor-based infinite scrolling and commit search. Guest users can
|
|
20
|
+
view the profile and sign in; journals require an approved device. Signed-in
|
|
21
|
+
users can publish commits, reply to a commit, or quote it. The modal composer
|
|
22
|
+
shows the original commit above the editor for replies and quotes, and submits
|
|
23
|
+
through the signed `POST /api/v1/commits` endpoint. Press `Ctrl+Q` or `Escape`
|
|
24
|
+
to close the composer.
|
|
25
|
+
|
|
26
|
+
The profile's **Sign in with GitHub** action starts the documented PKCE
|
|
27
|
+
device authorization flow. To preserve existing sign-ins, the app keeps its
|
|
28
|
+
dedicated Ed25519 keypair under `~/.dev-null-tui/` (directory mode `0700`,
|
|
29
|
+
private key mode `0600`, no passphrase). It opens the authorization page and,
|
|
30
|
+
after approval, signs `POST /api/v1/devices` with the `devnull-api` namespace.
|
|
31
|
+
The verifier and state remain in memory. The private key stays on the device
|
|
32
|
+
and is never included in API requests.
|
|
33
|
+
|
|
34
|
+
Before opening the authorization page, the app registers its per-user XDG
|
|
35
|
+
desktop handler for `devnull://` (no `sudo`). After approval, the handler
|
|
36
|
+
queues the callback for the running TUI, which checks the state before
|
|
37
|
+
redeeming the one-time code. Pasting the full `devnull://auth/callback?...`
|
|
38
|
+
URL remains available if callback handling is unavailable.
|
|
39
|
+
|
|
40
|
+
The device key stays in `~/.dev-null-tui/`. On each launch, the app checks that
|
|
41
|
+
key with a signed `GET /api/v1/me` and restores the profile when the device is
|
|
42
|
+
still approved. A revoked or unapproved key is retained, but the app remains
|
|
43
|
+
signed out so you can authorize a device again.
|
|
44
|
+
|
|
45
|
+
**Log out** removes the local private and public key files and clears the
|
|
46
|
+
in-memory session; callback handoff data and the callback-handler registration
|
|
47
|
+
are left untouched. This API does not expose a device-revocation endpoint, so
|
|
48
|
+
use [Settings → Devices](https://dev-null.sh/settings/devices) to revoke the
|
|
49
|
+
device's server-side approval too.
|
|
50
|
+
|
|
51
|
+
The handler can also be registered manually from the command line:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
uv run dev-null-tty --register-handler
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This registers a per-user XDG desktop entry for `devnull://` (no `sudo`). The
|
|
58
|
+
handler queues the callback in `~/.dev-null-tui/` with owner-only permissions;
|
|
59
|
+
the running TUI validates its state and removes the handoff file. Manual paste
|
|
60
|
+
remains available if registration is unavailable.
|
|
61
|
+
|
|
62
|
+
## Run
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uv run dev-null-tty
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Keyboard shortcuts:
|
|
69
|
+
|
|
70
|
+
- `h` / `l` — Previous / next journal
|
|
71
|
+
- `j` / `k` — Next / previous commit
|
|
72
|
+
- `Shift+C` — New commit
|
|
73
|
+
- `Shift+Q` — Quote selected commit
|
|
74
|
+
- `Shift+R` — Reply to selected commit
|
|
75
|
+
- `q` — Quit
|
|
76
|
+
|
|
77
|
+
## Test
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
uv run pytest
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Release
|
|
84
|
+
|
|
85
|
+
Configure a PyPI trusted publisher for this GitHub repository using the
|
|
86
|
+
`.github/workflows/publish.yml` workflow and the `pypi` environment. Update the
|
|
87
|
+
version in `pyproject.toml` (and refresh `uv.lock`), then push a matching
|
|
88
|
+
version tag, for example:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git tag v0.1.0
|
|
92
|
+
git push origin v0.1.0
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The workflow checks that the tag matches the project version, runs the tests,
|
|
96
|
+
builds the wheel and source distribution, and publishes them to PyPI using
|
|
97
|
+
OpenID Connect. No PyPI API token is required.
|
|
98
|
+
|
|
99
|
+
The upstream project is [nunomaduro/dev-null.sh](https://github.com/nunomaduro/dev-null.sh).
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# dev-null-tty
|
|
2
|
+
|
|
3
|
+
A keyboard-first terminal client for [/dev/null](https://dev-null.sh), built
|
|
4
|
+
with [Textual](https://textual.textualize.io/) and managed with
|
|
5
|
+
[uv](https://docs.astral.sh/uv/).
|
|
6
|
+
|
|
7
|
+
The **Following**, **Latest**, and **Trending** journals load real commits from
|
|
8
|
+
the signed `/api/v1/log/{log}` endpoint after sign-in. Each journal supports
|
|
9
|
+
automatic cursor-based infinite scrolling and commit search. Guest users can
|
|
10
|
+
view the profile and sign in; journals require an approved device. Signed-in
|
|
11
|
+
users can publish commits, reply to a commit, or quote it. The modal composer
|
|
12
|
+
shows the original commit above the editor for replies and quotes, and submits
|
|
13
|
+
through the signed `POST /api/v1/commits` endpoint. Press `Ctrl+Q` or `Escape`
|
|
14
|
+
to close the composer.
|
|
15
|
+
|
|
16
|
+
The profile's **Sign in with GitHub** action starts the documented PKCE
|
|
17
|
+
device authorization flow. To preserve existing sign-ins, the app keeps its
|
|
18
|
+
dedicated Ed25519 keypair under `~/.dev-null-tui/` (directory mode `0700`,
|
|
19
|
+
private key mode `0600`, no passphrase). It opens the authorization page and,
|
|
20
|
+
after approval, signs `POST /api/v1/devices` with the `devnull-api` namespace.
|
|
21
|
+
The verifier and state remain in memory. The private key stays on the device
|
|
22
|
+
and is never included in API requests.
|
|
23
|
+
|
|
24
|
+
Before opening the authorization page, the app registers its per-user XDG
|
|
25
|
+
desktop handler for `devnull://` (no `sudo`). After approval, the handler
|
|
26
|
+
queues the callback for the running TUI, which checks the state before
|
|
27
|
+
redeeming the one-time code. Pasting the full `devnull://auth/callback?...`
|
|
28
|
+
URL remains available if callback handling is unavailable.
|
|
29
|
+
|
|
30
|
+
The device key stays in `~/.dev-null-tui/`. On each launch, the app checks that
|
|
31
|
+
key with a signed `GET /api/v1/me` and restores the profile when the device is
|
|
32
|
+
still approved. A revoked or unapproved key is retained, but the app remains
|
|
33
|
+
signed out so you can authorize a device again.
|
|
34
|
+
|
|
35
|
+
**Log out** removes the local private and public key files and clears the
|
|
36
|
+
in-memory session; callback handoff data and the callback-handler registration
|
|
37
|
+
are left untouched. This API does not expose a device-revocation endpoint, so
|
|
38
|
+
use [Settings → Devices](https://dev-null.sh/settings/devices) to revoke the
|
|
39
|
+
device's server-side approval too.
|
|
40
|
+
|
|
41
|
+
The handler can also be registered manually from the command line:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
uv run dev-null-tty --register-handler
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This registers a per-user XDG desktop entry for `devnull://` (no `sudo`). The
|
|
48
|
+
handler queues the callback in `~/.dev-null-tui/` with owner-only permissions;
|
|
49
|
+
the running TUI validates its state and removes the handoff file. Manual paste
|
|
50
|
+
remains available if registration is unavailable.
|
|
51
|
+
|
|
52
|
+
## Run
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv run dev-null-tty
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Keyboard shortcuts:
|
|
59
|
+
|
|
60
|
+
- `h` / `l` — Previous / next journal
|
|
61
|
+
- `j` / `k` — Next / previous commit
|
|
62
|
+
- `Shift+C` — New commit
|
|
63
|
+
- `Shift+Q` — Quote selected commit
|
|
64
|
+
- `Shift+R` — Reply to selected commit
|
|
65
|
+
- `q` — Quit
|
|
66
|
+
|
|
67
|
+
## Test
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uv run pytest
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Release
|
|
74
|
+
|
|
75
|
+
Configure a PyPI trusted publisher for this GitHub repository using the
|
|
76
|
+
`.github/workflows/publish.yml` workflow and the `pypi` environment. Update the
|
|
77
|
+
version in `pyproject.toml` (and refresh `uv.lock`), then push a matching
|
|
78
|
+
version tag, for example:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
git tag v0.1.0
|
|
82
|
+
git push origin v0.1.0
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The workflow checks that the tag matches the project version, runs the tests,
|
|
86
|
+
builds the wheel and source distribution, and publishes them to PyPI using
|
|
87
|
+
OpenID Connect. No PyPI API token is required.
|
|
88
|
+
|
|
89
|
+
The upstream project is [nunomaduro/dev-null.sh](https://github.com/nunomaduro/dev-null.sh).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dev-null-tty"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A terminal interface for /dev/null"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = ["textual>=8.2.8"]
|
|
8
|
+
|
|
9
|
+
[[project.authors]]
|
|
10
|
+
name = "Avetis Avo Pisikyan"
|
|
11
|
+
email = "apisikya@gmail.com"
|
|
12
|
+
|
|
13
|
+
[project.scripts]
|
|
14
|
+
dev-null-tty = "dev_null_tty:main"
|
|
15
|
+
|
|
16
|
+
[build-system]
|
|
17
|
+
requires = ["uv_build>=0.12.10,<0.13.0"]
|
|
18
|
+
build-backend = "uv_build"
|
|
19
|
+
|
|
20
|
+
[dependency-groups]
|
|
21
|
+
dev = [
|
|
22
|
+
"pytest>=9.1.1",
|
|
23
|
+
"pytest-asyncio>=1.4.0",
|
|
24
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dev-null-tty"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A terminal interface for /dev/null"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Avetis Avo Pisikyan", email = "apisikya@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"textual>=8.2.8",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[project.scripts]
|
|
15
|
+
dev-null-tty = "dev_null_tty:main"
|
|
16
|
+
|
|
17
|
+
[build-system]
|
|
18
|
+
requires = ["uv_build>=0.12.10,<0.13.0"]
|
|
19
|
+
build-backend = "uv_build"
|
|
20
|
+
|
|
21
|
+
[dependency-groups]
|
|
22
|
+
dev = [
|
|
23
|
+
"pytest>=9.1.1",
|
|
24
|
+
"pytest-asyncio>=1.4.0",
|
|
25
|
+
]
|