gh-glance 0.13.3 → 0.14.1
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.
- package/CHANGELOG.md +100 -1
- package/README.md +46 -18
- package/index.mjs +963 -274
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,103 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.14.1] - 2026-09-08
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **A folder with no git remote opens in setup, not in a coordination wait.**
|
|
15
|
+
The onboarding prompt (`No GitHub remote found -- press Enter to create one`)
|
|
16
|
+
was only ever produced from a `gh` error, and with no remote there is no host
|
|
17
|
+
to verify an identity against, so no `gh` command ever ran: the dashboard sat
|
|
18
|
+
on "Can't coordinate API use -- retrying" and "waiting for API budget…" for a
|
|
19
|
+
repository that did not exist. The target is now decided before any
|
|
20
|
+
coordination -- no remote, no `--repo`, no `GH_REPO` means setup -- and
|
|
21
|
+
`--doctor` says so in the same words instead of reporting an unavailable
|
|
22
|
+
identity.
|
|
23
|
+
- **An upgrade no longer stalls on a ledger that never recorded a budget for a
|
|
24
|
+
resource it charged.** A 0.12-era file whose panes only ever observed GraphQL
|
|
25
|
+
holds core reservations with no core budget to date them by, so the migration
|
|
26
|
+
reported "older spend cannot be settled or waited out" -- a hold with no
|
|
27
|
+
deadline, on every launch, forever. Each reservation records the epoch it was
|
|
28
|
+
admitted against; that epoch's reset now serves as the deadline, and a window
|
|
29
|
+
that ended weeks ago clears at once.
|
|
30
|
+
|
|
31
|
+
## [0.14.0] - 2026-09-07
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- **`--background all|off`.** `off` never requests data for a tab you are not
|
|
36
|
+
looking at. Its tab-bar count keeps the last known value and ages visibly, and
|
|
37
|
+
switching to the tab fetches it. `--doctor` reports the setting alongside the
|
|
38
|
+
projected demand it changes.
|
|
39
|
+
- **`R` resynchronizes the current tab.** One generation without cached
|
|
40
|
+
validators, and the only key that clears a negative capability backoff -- so
|
|
41
|
+
an endpoint that answered "not enabled" can be re-asked on demand. Still
|
|
42
|
+
subject to the budget and the secondary cooldown.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- **The refresh floor is a floor, not a frequency.** A tab whose content is
|
|
47
|
+
unchanged twice in a row slows to 30 seconds (60 for Security), Actions with a
|
|
48
|
+
running or queued job is checked every 5, and an inactive tab is considered
|
|
49
|
+
every `max(12 x floor, 120s)` -- 300s for Security. An error or an unreadable
|
|
50
|
+
payload never counts as an unchanged observation, so a tab that cannot be read
|
|
51
|
+
is never slowed down for looking quiet. The one shared active floor and
|
|
52
|
+
rotating four-floor background slot could not express any of that, and only
|
|
53
|
+
Security ever slowed at all -- after a single unchanged poll, on a rule that
|
|
54
|
+
applied to nothing else.
|
|
55
|
+
- **`r` sends cached validators instead of throwing them away.** It remains a
|
|
56
|
+
prioritized refresh that bypasses the scheduled deadline and the tab's failure
|
|
57
|
+
ladder, but an unchanged tab now answers `304` and spends nothing -- the case
|
|
58
|
+
where the key is most likely to be pressed. Dropping validators is `R`. A
|
|
59
|
+
press arriving while automatic work that predates it is running schedules
|
|
60
|
+
exactly one follow-up rather than being lost, and further presses coalesce
|
|
61
|
+
into it.
|
|
62
|
+
- **Actions asks for one request, not two.** The runs list carries each run's
|
|
63
|
+
workflow name, so the workflow catalog became a conditional fallback for runs
|
|
64
|
+
that have none, cached for 15 minutes and separately admitted. The request is
|
|
65
|
+
also a stable 60-row variant rather than one derived from the pane's height,
|
|
66
|
+
so two differently sized panes ask the same question and can reuse each
|
|
67
|
+
other's validators. A catalog that cannot be read leaves the run list intact
|
|
68
|
+
with a missing or last-known name rather than blocking CI status.
|
|
69
|
+
- **Issues and Pull Requests load one 50-row page and page on demand.** The
|
|
70
|
+
first paint used to walk to 150 rows -- three requests for a pane showing
|
|
71
|
+
about twenty. Scrolling within ten rows of the end acquires exactly one more
|
|
72
|
+
page, capped at 150 rows, and repeated scrolling coalesces into a single
|
|
73
|
+
request. Rows carry truthful `totalCount`/`hasNextPage` markers, duplicates
|
|
74
|
+
across pages are removed, and a page from a traversal whose first page changed
|
|
75
|
+
underneath it is rejected rather than joined onto the new one.
|
|
76
|
+
- **`--doctor` reports a projected demand range.** The old line printed one
|
|
77
|
+
fixed figure as "this config spends", which read as a measurement; the cadence
|
|
78
|
+
now depends on what the repository is doing, so the report gives the range and
|
|
79
|
+
labels it a projection. Actual charges remain in the API governor section.
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
|
|
83
|
+
- **A separately admitted request was refused every single time.** Any second
|
|
84
|
+
request inside one tab fetch -- a later list page, the workflow catalog --
|
|
85
|
+
asks a moment after the tab's own grant advanced the shared lane, so the
|
|
86
|
+
governor answered with a slot a fraction of a second away. That answer was
|
|
87
|
+
treated as a refusal, which meant paged lists never paged and workflow names
|
|
88
|
+
never arrived. A named slot within a two-second bound is now waited out and
|
|
89
|
+
revalidated; a longer gap still declines, and a slot the request decides not
|
|
90
|
+
to take is released rather than left reserved against the budget.
|
|
91
|
+
- **Scrolling toward the end of a list re-fetched the same page.** The demanded
|
|
92
|
+
page count was computed and stored, then dropped by the Issues and Pull
|
|
93
|
+
requests tab definitions one call short of the fetcher, so a longer list could
|
|
94
|
+
never be paged into at all.
|
|
95
|
+
- **A refresh keypress arriving during a fetch was replayed as the stronger
|
|
96
|
+
key.** The queued handoff always resynchronized, so `r` dropped its validators
|
|
97
|
+
whenever it happened to land while an automatic poll was in flight. The queue
|
|
98
|
+
now carries which key was pressed.
|
|
99
|
+
- **A pane running an older build no longer makes the shared ledger
|
|
100
|
+
unreadable.** A pending request records exactly what its tab costs, so
|
|
101
|
+
changing that cost made every file written by a still-running older pane read
|
|
102
|
+
as corrupt -- discarding the leases and unsettled spend the restart boundary
|
|
103
|
+
depends on. Such a file is now recognized as older and adapted: its
|
|
104
|
+
differently priced pending requests are dropped, and every lease, budget and
|
|
105
|
+
unsettled charge is kept.
|
|
106
|
+
|
|
10
107
|
## [0.13.3] - 2026-09-07
|
|
11
108
|
|
|
12
109
|
### Changed
|
|
@@ -953,7 +1050,9 @@ engineering, security, QA and UX. What follows is what changed as a result.
|
|
|
953
1050
|
- The `main` field from `package.json`. It advertised the file as importable,
|
|
954
1051
|
but importing it took over the terminal or exited the host process.
|
|
955
1052
|
|
|
956
|
-
[Unreleased]: https://github.com/juan294/gh-glance/compare/v0.
|
|
1053
|
+
[Unreleased]: https://github.com/juan294/gh-glance/compare/v0.14.1...HEAD
|
|
1054
|
+
[0.14.1]: https://github.com/juan294/gh-glance/compare/v0.14.0...v0.14.1
|
|
1055
|
+
[0.14.0]: https://github.com/juan294/gh-glance/compare/v0.13.3...v0.14.0
|
|
957
1056
|
[0.13.3]: https://github.com/juan294/gh-glance/compare/v0.13.2...v0.13.3
|
|
958
1057
|
[0.13.2]: https://github.com/juan294/gh-glance/compare/v0.13.1...v0.13.2
|
|
959
1058
|
[0.13.1]: https://github.com/juan294/gh-glance/compare/v0.13.0...v0.13.1
|
package/README.md
CHANGED
|
@@ -247,7 +247,8 @@ stdout isn't a terminal rather than streaming redraw frames into a pipe.
|
|
|
247
247
|
| `↑` / `↓` or `j` / `k` | Move the cursor between rows |
|
|
248
248
|
| `PgUp` / `PgDn` | Move a page at a time |
|
|
249
249
|
| `Enter` | Open the selected item, or accept an onboarding prompt |
|
|
250
|
-
| `r` | Request a current-tab refresh
|
|
250
|
+
| `r` | Request a current-tab refresh. It sends the cached validators, so an unchanged tab answers `304` and spends nothing. A safe grant is still required. |
|
|
251
|
+
| `R` | Resynchronize the current tab: one generation without validators, and the only key that clears a negative capability backoff. Still subject to the budget and the secondary cooldown. |
|
|
251
252
|
| `w` | Adjust table column widths |
|
|
252
253
|
| `?` | Show the keys without leaving the dashboard (any key closes it) |
|
|
253
254
|
| `q` / `Esc` / `Ctrl+C` | Quit (`Esc` leaves width mode) |
|
|
@@ -317,8 +318,9 @@ pane definition. Flags are there when you want them:
|
|
|
317
318
|
| Flag | Effect |
|
|
318
319
|
|---|---|
|
|
319
320
|
| `-R`, `--repo [host/]owner/name` | Watch a specific repository instead of the current directory's. Works from anywhere -- you do not need a local clone. The optional host targets a GitHub Enterprise or EMU data-residency tenant, e.g. `tenant.ghe.com/acme/widget`. |
|
|
320
|
-
| `--refresh <seconds>` | Minimum active-tab poll interval, 2-3600, default 5.
|
|
321
|
+
| `--refresh <seconds>` | Minimum active-tab poll interval, 2-3600, default 5. A floor, never a ceiling: a tab whose content is unchanged twice in a row slows to 30 seconds (60 for Security), and Actions with a running or queued job is checked every 5. Safe shared grants can make any check later. |
|
|
321
322
|
| `--tab <name>` | Start on `actions`, `issues`, `prs` or `security`. |
|
|
323
|
+
| `--background <mode>` | `all` (default) or `off`. `off` never requests data for a tab you are not looking at. Its count keeps the last known value and ages visibly, and switching to the tab fetches it. |
|
|
322
324
|
| `--verbose` | Log one line per dashboard `gh` call to stderr, with timing and outcome. Credential lookup and the account-identity proof are deliberately excluded, so that they cannot log anything derived from a token. stderr must be redirected: `gh-glance --verbose 2>gh-glance.log`. |
|
|
323
325
|
| `--doctor` | Print a diagnostic report and exit. See [Diagnostics](#diagnostics). |
|
|
324
326
|
|
|
@@ -528,9 +530,23 @@ printed if `gh-glance` crashes.
|
|
|
528
530
|
The default five seconds is a healthy single-pane floor, not an unconditional
|
|
529
531
|
request frequency. Each check first needs an atomic grant from the private
|
|
530
532
|
governor shared by local panes using the same effective host and account
|
|
531
|
-
namespace.
|
|
532
|
-
|
|
533
|
-
|
|
533
|
+
namespace. Beyond that floor, the cadence follows what the repository is
|
|
534
|
+
actually doing:
|
|
535
|
+
|
|
536
|
+
| State | Earliest normal check |
|
|
537
|
+
|---|---|
|
|
538
|
+
| New subscription, or active data that just changed | Immediately once, then the floor |
|
|
539
|
+
| Actions with a running or queued run | `max(floor, 5s)` |
|
|
540
|
+
| Active Actions, Issues or Pull Requests unchanged twice | `max(floor, 30s)` |
|
|
541
|
+
| Active Security unchanged twice | `max(floor, 60s)` |
|
|
542
|
+
| Inactive Actions, Issues or Pull Requests | `max(12 x floor, 120s)` |
|
|
543
|
+
| Inactive Security | `max(12 x floor, 300s)` |
|
|
544
|
+
| `--background off`, any inactive tab | Never |
|
|
545
|
+
|
|
546
|
+
Two unchanged observations are required, not one, and an error or an unreadable
|
|
547
|
+
payload never counts as one: a tab that cannot be read is not a quiet tab. One
|
|
548
|
+
inactive tab is considered per wake, in rotation, so three of them falling due
|
|
549
|
+
together do not start together.
|
|
534
550
|
|
|
535
551
|
The resources are independent. Actions and Security spend REST `core` calls;
|
|
536
552
|
Issues and Pull Requests are sorted with `--search`, which routes them through
|
|
@@ -540,9 +556,14 @@ floor:
|
|
|
540
556
|
|
|
541
557
|
| Visible tab | REST / hour | GraphQL / hour |
|
|
542
558
|
|---|---|---|
|
|
543
|
-
| Actions | up to ~
|
|
544
|
-
| Issues or Pull Requests |
|
|
545
|
-
| Security | ~
|
|
559
|
+
| Actions | ~192 quiet, up to ~792 | ~120 |
|
|
560
|
+
| Issues or Pull Requests | ~102 | ~300 quiet, up to ~1,500 |
|
|
561
|
+
| Security | ~390 quiet, up to ~4,350 | ~120 |
|
|
562
|
+
|
|
563
|
+
The lower figure in each range is every tab at its quiet cadence; the upper is
|
|
564
|
+
the active tab at its floor with Actions busy. `--doctor` prints the same range
|
|
565
|
+
for the configuration you actually run, labelled `projected demand` to keep it
|
|
566
|
+
distinct from the charges the governor section reports.
|
|
546
567
|
|
|
547
568
|
Security is the most expensive. A repository whose newest alert pages are not
|
|
548
569
|
full uses the three base endpoint calls and lands near 2,280 REST requests per
|
|
@@ -577,10 +598,11 @@ probe, but it cannot yet prove the account-wide GraphQL reserve.
|
|
|
577
598
|
|
|
578
599
|
One pane owns the free `rate_limit` probe for a control window and publishes it
|
|
579
600
|
for the others. Manual and diagnostic work is considered before tab-switch,
|
|
580
|
-
active, and background work; equal-priority panes rotate fairly.
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
601
|
+
active, and background work; equal-priority panes rotate fairly. Both refresh
|
|
602
|
+
keys coalesce repeated presses -- a press during work that predates it schedules
|
|
603
|
+
exactly one follow-up -- and give immediate Watching or Paused feedback. Only
|
|
604
|
+
`R` clears validators and an endpoint backoff, and only after admission. Neither
|
|
605
|
+
can bypass a held budget or force a request into the reserve.
|
|
584
606
|
|
|
585
607
|
The shared lane uses spendable capacity, time to reset, outstanding
|
|
586
608
|
reservations, and observed external spend. Startup and each new reset epoch add
|
|
@@ -645,10 +667,16 @@ floor and shows Watching between checks.
|
|
|
645
667
|
reporting only after `w` enters width mode, and disable it when that mode or
|
|
646
668
|
the app exits. See [Adjusting column widths](#adjusting-column-widths) for
|
|
647
669
|
text-selection behavior while it is active.
|
|
648
|
-
- Issues and pull requests are fetched
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
670
|
+
- Issues and pull requests are fetched 50 at a time, up to 150 rows. Scrolling
|
|
671
|
+
within ten rows of what is loaded acquires the next page; a tab nobody scrolls
|
|
672
|
+
never asks for one. Each Security source has a newest-100 lane; full
|
|
673
|
+
Dependabot and code-scanning pages activate bounded priority lanes. A count is
|
|
674
|
+
shown as `n+` when any lane fills, so the number is never presented as exact
|
|
675
|
+
when it is not.
|
|
676
|
+
- Actions asks for the newest 60 runs, whatever the pane's height. Each run
|
|
677
|
+
carries its own workflow name; when a run has none, the workflow catalog is
|
|
678
|
+
fetched once and reused for 15 minutes, and a catalog that cannot be read
|
|
679
|
+
leaves the run's other columns intact.
|
|
652
680
|
- The Actions **TIME** column measures from the run's start to its last update.
|
|
653
681
|
`gh` exposes no completion timestamp, so a workflow that was re-run later
|
|
654
682
|
reports the span up to the re-run rather than its original duration.
|
|
@@ -690,7 +718,7 @@ GH_GLANCE_ICONS=ascii gh-glance
|
|
|
690
718
|
| `the gh CLI is not installed` | Install it from [cli.github.com](https://cli.github.com), then `gh auth login`. |
|
|
691
719
|
| `not inside a git repository` | Run it from a cloned GitHub repository, or set `GH_REPO=owner/name`. |
|
|
692
720
|
| `No GitHub remote found` | Press `Enter` to start `gh repo create`, then choose **Push an existing local repository**. Or press `q` and run `gh-glance --repo owner/name` to watch an existing repository without attaching this folder. |
|
|
693
|
-
| `GitHub login or authorization required` | Run `gh auth status`. With no account, run `gh auth login`; with an expired authorization, run `gh auth refresh`; then press `
|
|
721
|
+
| `GitHub login or authorization required` | Run `gh auth status`. With no account, run `gh auth login`; with an expired authorization, run `gh auth refresh`; then press `R`, which also clears the endpoint backoff the failures accrued. |
|
|
694
722
|
| `Repository not found or inaccessible to the active gh account` | The active identity cannot resolve the target. Check `gh auth status`, `git remote -v` or the explicit `--repo`, and use `gh auth switch` only if the wrong account is active. |
|
|
695
723
|
| `GraphQL: Could not resolve to a Repository...` in older gh-glance versions | The response has the same ambiguity: a missing or renamed target, or a private repository not visible to the active account. Run `gh-glance --doctor`. |
|
|
696
724
|
| Actions says `not available for this repository` while Repository access is `ok` | The repository resolved, but that endpoint is unavailable; inspect the corresponding doctor block. |
|
|
@@ -705,7 +733,7 @@ GH_GLANCE_ICONS=ascii gh-glance
|
|
|
705
733
|
| `Watching` with `sharing 4` | Four local panes share this account governor, and another pane owns the lane immediately ahead of this grant. This is pacing, not quota scarcity. |
|
|
706
734
|
| `Paused` with a reset time | The active tab's REST or GraphQL resource is at its reserve, exhausted, or under a shared rate-limit block. Wait for the stated reset/probe. Other tabs can continue when they use the healthy resource. |
|
|
707
735
|
| `Paused` without a reset time | Budget or coordinator evidence is unknown, corrupt, locked, or unwritable. No data call is started. Run `gh-glance --doctor`; also check the config directory permissions and whether another live process owns its private lock. |
|
|
708
|
-
| A failing tab seems to have stopped retrying | Recognized endpoint failures back off rather than re-spawning `gh` at the floor. Press `r` to request a higher-priority retry
|
|
736
|
+
| A failing tab seems to have stopped retrying | Recognized endpoint failures back off rather than re-spawning `gh` at the floor. Press `r` to request a higher-priority retry, or `R` to also clear the endpoint backoff; either way the retry waits for a safe grant, so the tab remains Watching or Paused. |
|
|
709
737
|
| `unknown argument: -v` | `-v` used to mean `--version` and no longer does, because this CLI also has `--verbose`. Use `--version` or `--verbose` explicitly. |
|
|
710
738
|
| Cached rows plus `Paused` and `stale 2m` | The rows came from the separate last-known-good dashboard cache, while the live request is blocked or unsafe. Stale age is not extended by a pause. The error and footer describe current coordination; cached data never means the live check succeeded. |
|
|
711
739
|
| Repeated GitHub rate-limit messages | A classified rate-limit response is published as one shared resource block. Local panes make no data retry before that block's probe/reset deadline. Use `--doctor` to inspect the resource and reset; repeated manual refresh cannot override it. |
|