queue-watch 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.5
2
+ Name: queue-watch
3
+ Version: 0.1.0
4
+ Summary: Read-only terminal dashboard for CI runs and merge queues, with mouse support
5
+ Project-URL: Homepage, https://github.com/wolfiesch/queue-watch
6
+ Project-URL: Issues, https://github.com/wolfiesch/queue-watch/issues
7
+ Project-URL: Changelog, https://github.com/wolfiesch/queue-watch/releases
8
+ Author: Wolfgang Schoenberger
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ci,dashboard,github-actions,merge-queue,textual,tui
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Build Tools
23
+ Classifier: Topic :: Software Development :: Testing
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: textual<7,>=6
26
+ Description-Content-Type: text/markdown
27
+
28
+ # queue-watch
29
+
30
+ Read-only terminal dashboard for CI runs and merge queues. It joins records from every source into one row per change, so a branch's CI runs and its merge-queue entry read together, and draws each merge queue as a chain of chips in queue order. queue-watch never reruns, cancels, merges or takes a lock.
31
+
32
+ ![queue-watch showing a merge queue of four changes, the Changes table grouped by state, and the inspector for a failed change](https://raw.githubusercontent.com/wolfiesch/queue-watch/main/docs/screenshot.png)
33
+
34
+ ## Install
35
+
36
+ ```sh
37
+ uv tool install queue-watch # or: pipx install queue-watch
38
+ uvx queue-watch # run once without installing
39
+ ```
40
+
41
+ Requires Python 3.11+. The GitHub adapters use an authenticated [GitHub CLI](https://cli.github.com/) (`gh auth login`).
42
+
43
+ ## Use
44
+
45
+ ```sh
46
+ queue-watch # inside a GitHub checkout
47
+ queue-watch --repo owner/repo # Actions plus the merge queue, if any
48
+ queue-watch --profile work # ~/.config/queue-watch/work.toml
49
+ queue-watch --config sources.toml # any combination of sources
50
+ queue-watch --repo owner/repo --once # one JSON snapshot, no TUI
51
+ queue-watch --theme nord --ascii # any Textual theme; ASCII glyphs only
52
+ queue-watch --density comfortable # title, owner and PR on a second line
53
+ ```
54
+
55
+ With no flags, queue-watch looks for a `.queue-watch.toml` at the root of the current Git checkout. Without one, it watches the checkout's GitHub repository: Actions runs, plus the merge queue when the default branch has one. `--profile NAME` reads `$XDG_CONFIG_HOME/queue-watch/NAME.toml` (default `~/.config`).
56
+
57
+ The Changes tab groups changes into Needs attention, Running, Queued and Done; every view a source reports also gets its own tab. Done starts folded while any other group has changes; press enter on a group row, or click it, to fold or unfold it. Select a change or a queue chip to see its CI checks, the jobs of the most notable one, its queue position and ETA, and recent history in the inspector.
58
+
59
+ Each merge queue gets a strip above the tabs: its entries in merge order, when it should clear, merges in the last hour, and how long recent attempts took. Queue depth over the session appears as a sparkline once two fetches have answered; sources report only the current queue, so the history starts when queue-watch does. On terminals under 30 rows the entries shrink to one line each.
60
+
61
+ Keyboard: arrows to move, `1` to `9` for tabs, `/` to search (esc to clear), `o` to open the selection in a browser, `c` to copy its SHA, `d` to switch row density, `r` to refresh, `p` to pause, `q` to quit. The mouse works too: click tabs, rows, chips and the inspector buttons, and scroll with the wheel. When a source fails, its last good data stays on screen and its status pill turns stale.
62
+
63
+ ### Repository configs need trust
64
+
65
+ A config can run commands and open SSH connections, so a `.queue-watch.toml` that arrives with a clone does nothing until you review it and run:
66
+
67
+ ```sh
68
+ queue-watch trust
69
+ ```
70
+
71
+ Trust covers the file's exact bytes (SHA-256, stored in `$XDG_STATE_HOME/queue-watch/trusted.json`). After any edit, queue-watch refuses the file and names the command to run again. Files passed with `--config` or `--profile` are yours and load without this step.
72
+
73
+ ## Sources
74
+
75
+ A config file lists sources as `[[source]]` tables. `id` and `adapter` are required; `label` and `interval` (seconds) are optional; every other key is an adapter option.
76
+
77
+ ```toml
78
+ [[source]]
79
+ id = "ci"
80
+ adapter = "github-actions"
81
+ repo = "owner/repo"
82
+
83
+ [[source]]
84
+ id = "merge-queue"
85
+ adapter = "github-merge-queue"
86
+ repo = "owner/repo"
87
+ branch = "main" # optional; default branch otherwise
88
+
89
+ [[source]]
90
+ id = "deploys"
91
+ adapter = "command"
92
+ command = ["./bin/deploy-status", "--json"]
93
+ timeout = 20 # optional seconds, default 25
94
+
95
+ [[source]]
96
+ id = "merges"
97
+ adapter = "flock-queue"
98
+ host = "build-host" # optional SSH destination
99
+ root = "~/src/project" # Git checkout that defines {git_dir}
100
+ lock = "{git_dir}/merge.lock"
101
+ tickets = "{git_dir}/merge.queue/*.ticket"
102
+ process = "merge.py"
103
+ owner_flag = "--owner"
104
+ history = "{git_dir}/merge-history.jsonl"
105
+ history_columns = [{ key = "fields.duration_seconds", label = "Took", format = "seconds" }]
106
+ ```
107
+
108
+ | Adapter | Watches | Options |
109
+ |---|---|---|
110
+ | `github-actions` | Workflow runs, with jobs and steps in the inspector | `repo` |
111
+ | `github-merge-queue` | GitHub's native merge queue: position, state, author and GitHub's merge estimate per pull request | `repo`, `branch` |
112
+ | `command` | Anything else: a program that prints one snapshot | `command`, `host`, `cwd`, `timeout` |
113
+ | `flock-queue` | A Linux FIFO of flock-held ticket files guarding one merge lock, plus an optional JSON Lines attempt log | `lock`, `tickets`, `process`, `root`, `host`, `interpreters`, `owner_flag`, `history`, `history_limit`, `history_columns` |
114
+
115
+ Merge queue states map as `QUEUED` and `MERGEABLE` to queued, `AWAITING_CHECKS` and `LOCKED` to running, and `UNMERGEABLE` to blocked. A branch without a queue shows a warning instead of an error.
116
+
117
+ `flock-queue` reads lock holders from `/proc/locks` rather than acquiring them. With `host` set, the probe goes to `python3 -` over SSH on stdin and nothing is installed on the host.
118
+
119
+ ### Command sources
120
+
121
+ Use the `command` adapter for GitLab, Buildkite, Jenkins, Bors or an in-house queue. `command` is an argument list run without a shell. Locally it runs in `cwd`, which defaults to the config file's directory; relative paths resolve against that directory too. With `host` set, it runs over SSH (`BatchMode`, every argument quoted for the remote shell), in `cwd` on the host when given.
122
+
123
+ The program must exit zero and print one snapshot (below) on stdout within `timeout` seconds. Anything else, including a snapshot that breaks the contract, shows as a source error while the last good data stays on screen. [`examples/`](https://github.com/wolfiesch/queue-watch/tree/main/examples) has a working script and config.
124
+
125
+ ## Snapshot contract
126
+
127
+ Every adapter emits the same versioned snapshot (`queue-watch.snapshot/1`): a list of records with `id`, `kind`, `state` and `title`, plus optional `ref`, `sha`, `owner`, `position`, timestamps, `url`, `fields` and `children`. `state` is one of `queued`, `running`, `blocked`, `success`, `failure`, `cancelled`, `neutral` or `unknown`; the adapter's own term is kept in `raw_state`. Records that share a `ref` or `sha` describe the same change across sources. [`model.py`](https://github.com/wolfiesch/queue-watch/blob/main/src/queue_watch/model.py) defines and validates the contract, and `--once` prints it.
128
+
129
+ ## Development
130
+
131
+ ```sh
132
+ uv sync
133
+ uv run pytest -q # includes SVG snapshot tests
134
+ uv run pytest -q --snapshot-update # after an intended layout change
135
+ ```
136
+
137
+ `docs/screenshot.png` is the wide layout snapshot rendered in a browser. To release, bump `__version__` in `src/queue_watch/__init__.py`, merge, and push a matching `vX.Y.Z` tag; the release workflow tests, builds, publishes to PyPI with trusted publishing, and creates the GitHub release.
138
+
139
+ ## License
140
+
141
+ MIT
@@ -0,0 +1,19 @@
1
+ queue_watch/__init__.py,sha256=Et5F4b-CXY5wbs5dYw7ZsLbuTxmhuVI5EPOg-1ssgso,88
2
+ queue_watch/app.py,sha256=H6zkvLQs8DKjQNq3smrj3ReWujExQkr0RypEFVPkxgI,36828
3
+ queue_watch/changes.py,sha256=7rwtEm8vWHQH7Ra1IhxLX7GeGgLXm0QTvhU93oU7OzY,6379
4
+ queue_watch/cli.py,sha256=AGHMbKuf1e-Ah3NWpTUNLzonxfwI2_J4Fe8j4hEAAX0,5269
5
+ queue_watch/config.py,sha256=Ig3i5AXyWPKjlZoRuXDghmOTMGShcCpmf6yg96T0A7g,3672
6
+ queue_watch/discovery.py,sha256=BwKx5JU6A115hqJmJbEqP845Kx8oR0X2lKQjfRyZEWA,4890
7
+ queue_watch/model.py,sha256=Vp0i4OBHCn7VRJ-93XJfBfX7cvCy4W5NRLA7Gh5E8Mw,7896
8
+ queue_watch/process.py,sha256=JkqioMiWoKoNb0IrPBekz4GGOE1jvZbfgo3L6FUYc1w,2610
9
+ queue_watch/widgets.py,sha256=aLwlecVY_x9yYPmnzxmocqr16sRE9ZYeNpdHN6mrwDk,28667
10
+ queue_watch/adapters/__init__.py,sha256=v9qpSUMFtJNNb4N7paQaDrfxiGlH7BmQqM14A8W5IT4,1101
11
+ queue_watch/adapters/command.py,sha256=dxATISUXWNuQmFTQxq8zeuJINq9p6OssaZZEPw1Q1qY,1990
12
+ queue_watch/adapters/flock_queue.py,sha256=EHKB1wLqVF0qui7qdHkIeJs-mMfQ6qtRGJ-GPXYzY6I,11847
13
+ queue_watch/adapters/github_actions.py,sha256=v3QxW_agqd4GJUd59ZE1iPw52hoOGFivz1w46xeVoqs,6118
14
+ queue_watch/adapters/github_merge_queue.py,sha256=ZpRYlyfEoWSai2DtoP5CE6QVBUdTu3yx_XvgFlDgiYs,5140
15
+ queue_watch-0.1.0.dist-info/METADATA,sha256=Oq0Pz9DgKuqBBKgJ5p-dAmDP7F3sSF_67Svmi8wl4PQ,8376
16
+ queue_watch-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
17
+ queue_watch-0.1.0.dist-info/entry_points.txt,sha256=vpoaPvrxU-TWgiVefYwd2kFh22naV-OMAVkqVM3XUn8,53
18
+ queue_watch-0.1.0.dist-info/licenses/LICENSE,sha256=JKzPXq3f7o1e4rX_LdIS1izSmmLRlPsMW8aBssenlzA,1078
19
+ queue_watch-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ queue-watch = queue_watch.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wolfgang Schoenberger
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.